1

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
2
  • You better use const char*for b unless you intend to change the characters in the string. Commented Apr 28, 2017 at 7:41
  • 4
    Pick one language, not two. C and C++ are different here. Commented Apr 28, 2017 at 7:43

5 Answers 5

7

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 *.

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

4 Comments

Note that assigning a string literal to a non-const char* pointer is deprecated in C++11.
BTW, it's only valid C++ before C++11; after that, dropping the const was disallowed.
OK, I was concentrating on the C tag..Will add this info into the answer.
@RemyLebeau it was deprecated in C++03, and an error in C++11
5

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

4 Comments

so the c pointer will point to "abcd" isn't pointer supposed to point at the address or else it will output an error if pointed to anything else?
@sorryiamrookie It will point at the address where the literal "abcd" is stored. Which, as it turns out, is a read-only address. So if you attempt to modify the contents there, the program might crash. Therefore it is good practice to always use const char* c when pointing at string literals, in C and C++ both.
To be more precise, in this particular case, conversion of a string literal to a non-const pointer was deprecated in C++03 (i.e. it was still legal but slated for removal in a future standard) and finally removed in C++11. A consequence of this is that code using such a conversion would legally compile until C++11, but compilers would (if configured appropriately to give warnings) give a warning about it. Such an implicit conversion is illegal in C++, so will not compile, only since C++11.
In c you have to always compile with gcc flag ` -Wwrite-strings` to check and warn you in case you forget the const for literals but in C++ is enabled by default.
1

"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).

2 Comments

Oops. Time for a coffee.
@M.M. Time for another coffee - perhaps I'll dig out my university notes out from the loft at the weekend ;-)
0

"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.

12 Comments

The string literal (an array essentially) will decay to a pointer type due to interoperability rules. An int will not decay into a pointer-to-int. Have you tried compiling the code on "every compiler"? Mine certainly won't. (Thankfully)
" sequence of five bytes 97 98 99 100 0" - assuming a particular encoding, not guaranteed. The last byte is always 0 though.
@sigbjornlo Yours most certainly will with the right prompting, because this sort of code is still quite common.
@Bathsheba What part of sorryiamrookie's question made you think that they have any access to a non-ASCII system?
The tags on the question.
|
0

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, e.g.

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.

8 Comments

While very correct, this is probably not what OP is looking for. There is a difference between "abcd" and 1 and OP looks to be interested in that. :)
It was kind of hard to tell. This was the only way I could think of to initialize an int * from a literal 1, in order to make what it looked like he was trying to do -- work.
The int *c= (int[]){ 1 }; takes the address of a temporary array.
@DavidC.Rankin as I said, you are not at all wrong, it's just IMHO, not in the correct context, that's all. Again, it's just my opinion.
By "subtle differences" you mean that C has compound literals and C++ does not
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.