Asked by:
Visual Studio 2015 Update 1 implicit string narrow wide conversion and _CONVERSION_DONT_USE_THREAD_LOCALE

Question
-
Hello,
I want to use the feature of the CStringW to implicitly convert a narrow string to a wide string in the constructor with the CP_ACP conversion rule. In order to use this you have to define the _CONVERSION_DONT_USE_THREAD_LOCALE, this works with the A2W macros as expected - in atlconv.h the function AtlA2WHelper is called with acp == 0 == CP_ACP, but not for the CStringW constructor that calls operator= in cstringt.h. This operator calls StringTraits::ConvertToBaseType that calls MultiByteToWideChar with the first parameter returned by the function _AtlGetConversionACP that is always 3 == CP_THREAD_ACP and never CP_ACP.
// Compile with _CONVERSION_DONT_USE_THREAD_LOCALE defined in C/C++ Preprocessor definitions // OS set to "Greek" char* s = "äöü"; CStringW sw(s); // sic! always CP_THREAD_ACP is passed to MultiByteToWideChar even if _CONVERSION_DONT_USE_THREAD_LOCALE is defined USES_CONVERSION; CStringW sww(A2W(s)); // works as expected, AtlA2WHelper is called with CP_ACP that is passed to MultiByteToWideChar
Thanks for the help,
Andreas
Tuesday, March 22, 2016 8:50 AM
All replies
-
In my copy of VC++2015 Community Update 1 the _AtlGetConversionACP function is at line 104 of atlconv.h and appears as
inline UINT WINAPI _AtlGetConversionACP() throw() { #ifdef _CONVERSION_DONT_USE_THREAD_LOCALE return CP_ACP; #else return CP_THREAD_ACP; #endif }
I don't understand how it could return CP_THREAD_ACP if _CONVERSION_DONT_USE_THREAD_LOCALE has been defined.
Tuesday, March 22, 2016 11:51 AM -
char* s = "äöü"; CStringW sw(s); // sic! always CP_THREAD_ACP is passed to MultiByteToWideChar even if _CONVERSION_DONT_USE_THREAD_LOCALE is defined USES_CONVERSION;
Hi,
I am sorry. Could you please provide me more information, I am confused. If you use the new ATL 7.0 Conversion classes, you never require USES_CONVERSION to be defined.
If you have free time, please see the ATL and MFC String Conversion Macros.
https://msdn.microsoft.com/en-us/library/87zae4a3(v=vs.90).aspx
Best Regards,
Hart
Wednesday, March 23, 2016 6:30 AM -
Seems that you have to recompile the MFC library, since it was built with different value of _CONVERSION_DONT_USE_THREAD_LOCALE.
Another workaround: use CW2A or CW2AEX with CP_ACP argument.
Wednesday, March 23, 2016 6:54 AM -
You are right, I don't need the USES_CONVERSION any more, copied the lines from a very old project - but that is not the matter - the question was about CStringW's implicit narrow to wide conversion.
Andreas
Wednesday, March 23, 2016 8:21 AM -
the question was about CStringW's implicit narrow to wide conversion.
Andreas
Hi,
Based on my research. CStringW is the wide character string only version. I don’t understand this sentence.
You can see the MSDN document to understand the CStringW.
https://msdn.microsoft.com/en-us/library/ms235631.aspx
Best Regards,
Hart
Wednesday, March 23, 2016 9:07 AM -
the question was about CStringW's implicit narrow to wide conversion.
Andreas
Hi,
Based on my research. CStringW is the wide character string only version. I don’t understand this sentence.
You can see the MSDN document to understand the CStringW.
https://msdn.microsoft.com/en-us/library/ms235631.aspx
Best Regards,
Hart
Wednesday, March 23, 2016 9:59 AM -
Hi,
Yes, thanks for explanation, I also reproduce the issue. As end-user I don’t know why the Microsoft designed.
Best Regards,
Hart
- Edited by Hart Wang Thursday, March 24, 2016 6:41 AM
Thursday, March 24, 2016 6:38 AM -
I submitted this issue to Microsoft connect, see https://connect.microsoft.com/VisualStudio/feedback/details/2508989
Please vote that you can reproduce it.
Thanks,
Andreas
- Proposed as answer by Hart Wang Friday, March 25, 2016 6:59 AM
Thursday, March 24, 2016 10:25 AM -
Hi,
Yes, thanks for explanation, I also reproduce the issue. As end-user I don’t know why the Microsoft designed.
Thursday, March 24, 2016 11:20 AM -
Hi,
Yes, thanks for explanation, I also reproduce the issue. As end-user I don’t know why the Microsoft designed.
This is unclear. Were you able to reproduce the issue described by the original poster regarding incorrect use of CP_THREAD_ACP or are you saying that you now understand that the CStringW class includes a constructor that accepts narrow character strings?
Hi,
I say that i now understand that the CStringW class includes a constructor that accepts narrow character strings.
Best Regards,
Hart
Friday, March 25, 2016 6:59 AM -
I say that i now understand that the CStringW class includes a constructor that accepts narrow character strings.
Best Regards,
Hart
Thank you for the clarification. I suggest you visit the issue opened by the original poster at https://connect.microsoft.com/VisualStudio/feedback/details/2508989 since it asserts that you were able to reproduce the original poster's CP_THREAD_ACP issue.
Friday, March 25, 2016 10:35 AM -
I submitted this issue to Microsoft connect, see https://connect.microsoft.com/VisualStudio/feedback/details/2508989
Frankly I do not know why you are bothering with this automatic conversion feature in CString. I regard this feature as extremely dangerous, and I think your post is an illustration of that fact.
I have banished use of the local code page from my code, but sometimes I use both UTF-8 and UTF-16 in an application. My most feared failure case is
CString str(someUtf8String);
Actually, if CString could be configured to use UTF-8 as the 8-bit character set, I might consider using the automatic conversion, but AFAIK it can't.
David Wilkinson | Visual C++ MVP
Friday, March 25, 2016 1:42 PM -
>> I submitted this issue to Microsoft connect, see https://connect.microsoft.com/VisualStudio/feedback/details/2508989
I think the bug report is worthwhile if it only serves to get MS to
mark the conversion constructor as deprecated - with a note to not use
ii because of this issue.Dave
Friday, March 25, 2016 6:50 PM -
So far the issue has not been reproduced by any of the folks who have responded to the post.Friday, March 25, 2016 6:57 PM
-
Alexander [MSFT] could reproduce this issue, see https://connect.microsoft.com/VisualStudio/feedback/details/2508989/implicit-string-narrow-wide-conversion-and-conversion-dont-use-thread-locale-does-not-work-as-expected
he recommends statically linking against MFC - no option for me.
he suggest making the conversion explicitly and use use the ATL 7.0 string conversion macros - I want to get rid of all this "ugly" macro stuff.
It would be very nice if the developer team of MFC would solve this issue and I could use the ctor that does all the stuff and I could get rid of this "ugly" macro stuff from my code.
And also resolve the CArchive problem when _CSTRING_DISABLE_NARROW_WIDE_CONVERSION is defined:
Andreas
Thursday, May 19, 2016 9:45 AM -
It appears that the MFC Dlls are the culprit in this case. That explains why any attempt to replicate the issue using ATL without dynamically linked MFC was unsuccessful.
It seems that there will always be a risk that distributed Dlls have been created using choices that later conflict with those made by the developer.
Perhaps these things should be documented by MS so that it doesn't require a bug hunt to resolve unexpected behavior?
Thursday, May 19, 2016 10:12 AM -
Thursday, May 19, 2016 10:34 AM
-
he suggest making the conversion explicitly and use use the ATL 7.0 string conversion macros - I want to get rid of all this "ugly" macro stuff.
The ATL 7.0 converions, such as CA2W, are not macros, they are classes. They do not require USES_CONVERSION.
Personally, I much prefer explicit use of these conversion classes to using a hidden (mis-)feature of CString.
David Wilkinson | Visual C++ MVP
Friday, May 20, 2016 10:25 AM -
The reason for this is that the MFC variant of CString use an instance of _AtlGetConversionACP() that is already compiled into the MFC dll.
_CONVERSION_DONT_USE_THREAD_LOCALE only works for CAtlString.
If you don't use MFC, CString is typedef'ed CAtlString (aka the ATL variant of CString), and this then of course works for both type names.
If you use the type CAtlString it works even when using MFC.
Thursday, October 20, 2016 8:25 PM