Jump to content
alank2

Compilng in x64 gives a warning I see why occurs

Recommended Posts

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
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 by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×