Question

I am porting an older project from C++ Builder 2009 to XE5. In the old project, the compiler option for Unicode strings was set as "_TCHAR maps to: char". This worked fine in the old project.

When porting it, I set the same compiler option in XE5. But I still get compiler errors for code like this:

std::string str = String(some_component.Text).t_str();

This gives the following errors:

[bcc32 Warning] file.cpp(89): W8111 Accessing deprecated entity 'UnicodeString::t_str() const'

[bcc32 Error] file.cpp(89): E2285 Could not find a match for 'operator string::=(wchar_t *)'

So apparently XE5 has decided that String::t_str() should give me a wchar_t* rather than a char*, even though I have set the compiler option as described above.

How do I solve this?

I am well-aware that C++ Builder has taken the step to use Unicode internally (even in the 2009 version), but this is an old project with 200k LOC. Updating it to Unicode would be a steep task with very low priority.

EDIT

I can get it to work by changing the code to

std::string str = AnsiString(some_component.Text).c_str();

But this means I have to change the code at numerous places. Is there a better way that doesn't involve rewriting code?

Was it helpful?

Solution

When UnicodeString::t_str() was first introduced in CB2009, it returned either a char* or wchar_t* depending on what TCHAR mapped to. In order to return a char*, it ALTERED the internal data of the UnicodeString to make it Ansi (thus breaking the contract that UnicodeString is a Unicode string). THIS WAS TEMPORARY for migration purposes while people were still re-writing their code to support Unicode. This breakage was acceptable because the RTL had special logic to handle Ansi-encoded UnicodeString (and Unicode-encoded AnsiString) values. However, this was dangerous code. After a few versions, when people had adequate time to migrate, this RTL logic was removed and UnicodeString::t_str() was locked in to wchar_t* only, to match UnicodeString::c_str(). DO NOT USE t_str() anymore! That is why it is marked as deprecated now. If you need to pass a UnicodeString to something that expects Ansi data, converting to an intermediate AnsiString is the correct and safe approach. That is just the way it is now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top