5

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.

1
  • 5
    VS12 speaks some strange dialect that is similar, but not identical to, C++. Commented Aug 24, 2013 at 21:18

3 Answers 3

8

The type of a string literal is indeed const char[SIZE] where SIZE 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.

But I don't see how it could be const char * as the following line is accepted by VS12: char* s = "Hello";

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.

Sign up to request clarification or add additional context in comments.

2 Comments

The "usual array-to-pointer decay" does not occur in all contexts. In C, it occurs unless the array expression is the operand of unary & or sizeof, or is a string literal in an initializer used to initialize an array (sub)object. C++ has more exceptions.
The correct term is the Array-to-pointer Conversion, which is a Standard Conversion documented in clause 4 of the latest C++ standard. Roughly speaking, standard conversions may be applied implicitly to expressions by the compiler in certain contexts.
5

The type of a string literal is char const[N] where N is the number of characters including the terminating null character. Although this type does not convert to char*, the C++ standard includes a clause allowing assignments of string literal to char*. This clause was added to support compatibility especially for C code which didn't have const back then.

The relevant clause for the type in the standard is 2.14.5 [lex.string] paragraph 8:

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).

2 Comments

Note that this exceptional clause is now deprecated, and trying to assign a string literal to a char* should yield a compile-time error.
@syam - "deprecated" means that it is still legal, but could go away in the future. The conversion of a string literal to a char* was deprecated in C++03; it became invalid in C++11. However, the language definition does not require a "compile-time error". For violations of diagnosable constraints, the only requirement is that the compiler issue a diagnostic; having done that, it is free to continue compiling the code. That's the hook for implementation-specific extensions. There is only one situation that requires a compiler to refuse to compile code: a #error directive.
-1

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:

wchar_t* s = L"hello"

7 Comments

This was not meant to be valid code, only a test to see the given error. The standard really makes it sound like it should be an array, though.
No, a string literal is not a const char* but a const char[SIZE] as explained in other answers. -1
Then explain why sizeof "hello, world" yields 13.
@Keith: you get a closing 0 for free when initializing a string constant.
@Jongware I know that. I'm asking Paul Evans to explain why it's not the same as sizeof (const char*). (And yes, I know that too.)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.