Out of curiosity, I'm wondering what the real underlying type of a C++ string literal is.
Depending on what I observe, I get different results.
A typeid test like the following:
std::cout << typeid("test").name() << std::endl;
shows me char const[5]
.
Trying to assign a string literal to an incompatible type like so (to see the given error):
wchar_t* s = "hello";
I get a value of type "const char *" cannot be used to initialize an entity of type "wchar_t *"
from VS12's IntelliSense.
But I don't see how it could be const char *
as the following line is accepted by VS12:
char* s = "Hello";
I have read that this was allowed in pre-C++11 standards as it was for retro-compatibility with C, although modification of s
would result in Undefined Behavior. I assume that this is simply VS12 having not yet implemented all of the C++11 standard and that this line would normally result in an error.
Reading the C99 standard (from here, 6.4.5.5) suggests that it should be an array:
The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.
So, what is the type underneath a C++ string literal?
Thank you very much for your precious time.
First off, the type of a C++ string literal is an array of n
const char
. Secondly, if you want to initialise a wchar_t with a string literal you have to code:The type of a string literal is
char const[N]
whereN
is the number of characters including the terminating null character. Although this type does not convert tochar*
, the C++ standard includes a clause allowing assignments of string literal tochar*
. This clause was added to support compatibility especially for C code which didn't haveconst
back then.The relevant clause for the type in the standard is 2.14.5 [lex.string] paragraph 8:
The type of a string literal is indeed
const char[SIZE]
whereSIZE
is the length of the string plus the null terminating character.The fact that you're sometimes seeing
const char*
is because of the usual array-to-pointer decay.This was correct behaviour in C++03 (as an exception to the usual const-correctness rules) but it has been deprecated since. A C++11 compliant compiler should not accept that code.