简体   繁体   中英

how is char * to string literal valid?

So from my understanding pointer variables point to an address. So, how is the following code valid in C++?

char* b= "abcd"; //valid
int *c= 1; //invalid

The first line

 char* b= "abcd";

is valid in C, because "string literals", while used as initializer, boils down to the address of the first element in the literal, which is a pointer (to char ).

Related, C11 , chapter §6.4.5, string literals,

[...] The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char , and are initialized with the individual bytes of the multibyte character sequence. [...]

and then, chapter §6.3.2.1 ( emphasis mine )

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array , an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue.

However, as mentioned in comments, in C++11 onwards, this is not valid anymore as string literals are of type const char[] there and in your case, LHS lacks the const specifier.

OTOH,

 int *c= 1;

is invalid (illegal) because, 1 is an integer constant, which is not the same type as int * .

In C and very old versions of C++, a string literal "abcd" is of type char[] , a character array. Such an array can naturally get pointed at by a char* , but not by a int* since that's not a compatible type.

However, C and C++ are different, often incompatible programming languages. They dropped compatibility with each other some 20 years ago.

In standard C++, a string literal is of type const char[] and therefore none of your posted code is valid in C++. This won't compile:

char* b = "abcd";        //invalid, discards const qualifier

This will:

const char* c = "abcd";  // valid

"abcd" is actually a const char[5] type, and the language permits this to be assigned to a const char* (and, regrettably, a char* although C++11 onwards disallows it.).

int *c = 1; is not allowed by the C++ or C standards since you can't assign an int to an int* pointer (with the exception of 0 , and in that case your intent will be expressed clearer by assigning nullptr instead).

"abcd" is the address that contains the sequence of five bytes 97 98 99 100 0 -- you cannot see what the address is in the source code, but the compiler will still assign it an address.

1 is also an address near the bottom of your [virtual] memory. This may not seem to be useful to you, but it is useful to other people , so even though the "standard" might not want to permit this, every compiler you are ever likely to run into will support this.

While all other answers give the correct answer of why you code doesn't work, using a compound literal to initialize c , is one way you can make your code work, eg

int *c= (int[]){ 1 };
printf ("int pointer c : %d\n", *c);

Note, there are differences between C and C++ in the use of compound literals, they are only available in C.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM