alank2 5 Posted November 18, 2021 The warning is: [bcc64 Warning] file.cpp(1336): ISO C++11 does not allow conversion from string literal to 'wchar_t *' It is from: wchar_t *ConfigurationResultText[]={ L"No error", L"CFGERROR: Unable to create file", L"CFGERROR: Unable to open file or file is busy", L"CFGERROR: Unable to perform file IO", L"CFGERROR: File is not a CFG file", }; It seems that if I put (whcar_t*) before each string, that it eliminates the warning. My question is why? Doesn't the L"string" already mean it is a wchar_t * ? Or does the clang compiler see it as something different? I usually use the classic compiler, but in x64 that is not an option. Share this post Link to post
Remy Lebeau 1428 Posted November 18, 2021 (edited) 4 hours ago, alank2 said: The warning is: [bcc64 Warning] file.cpp(1336): ISO C++11 does not allow conversion from string literal to 'wchar_t *' In C++11 onward, a string literal (in your case, each string literal is a 'const wchar[N]' array) cannot be assigned to a pointer-to-non-const, as that promotes the ability to modify read-only data at runtime. In C, and prior to C++11, such an assignment was allowed. But BCC64 is a clang-based compiler that supports C++11, hence the warning (which is really an error nowadays). This is actually documented (albeit briefly) on Embarcadero's DocWiki: Common Warnings Porting from BCC32: Conversion from string literal to 'char *' is deprecated Quote Assigning a plain char pointer to a literal C-string is discouraged. Make the pointer const (and if appropriate, consider using std::string). Stricter C++ Compilers: Type Conversions Quote Assigning literal C-strings to char * generates a warning unless that pointer is declared const. 4 hours ago, alank2 said: It seems that if I put (whcar_t*) before each string, that it eliminates the warning. Yes, but don't do that. The correct solution is to make your array hold pointer-to-const elements instead (which you should have done from the very beginning), eg: const wchar_t *ConfigurationResultText[]={ // or wchar_t const * L"No error", L"CFGERROR: Unable to create file", L"CFGERROR: Unable to open file or file is busy", L"CFGERROR: Unable to perform file IO", L"CFGERROR: File is not a CFG file", }; 4 hours ago, alank2 said: My question is why? Because it is required in C++11 onward. Assigning a string literal (which decays into a pointer-to-const) to a pointer-to-non-const was bad practice in earlier versions, so the C++ committee finally closed that hole. 4 hours ago, alank2 said: Doesn't the L"string" already mean it is a wchar_t * ? It is a 'const wchar[N]' array that decays into a 'const wchar_t*' pointer, not a 'wchar_t*' pointer. 4 hours ago, alank2 said: I usually use the classic compiler, but in x64 that is not an option. The classic compiler is not a clang-based compiler, and does not support C++11 (but has some C++11 features, but this isn't one of them). But adding the 'const' to the array element type will work in the classic compiler, too. If you run into a problem where you need to pass your string literal pointers to a legacy API that takes a pointer-to-non-const rather than a pointer-to-const, then you can type-cast (preferably using 'const_cast', not a C-style cast) at the call site, not in your array itself, eg: const wchar_t *ConfigurationResultText[]={ // or wchar_t const * L"No error", ... }; ... someLegacyFunction(const_cast<wchar_t*>(ConfigurationResultText[index])); Edited November 18, 2021 by Remy Lebeau Share this post Link to post
alank2 5 Posted November 18, 2021 Thank you Remy - that explains it. I appreciate the detailed explanation! Share this post Link to post
uligerhardt 18 Posted November 19, 2021 Would be nice if the warning specified that non-const aspect. 😉 Share this post Link to post