4

Why is the first line valid but the rest invalid. I though the first was a shorthand for the second.

const char *c = "abc"; // Why valid?

const char *b = { 'a' , 'b', 'c', '\0' }; // invalid

const int *a = { 1, 2, 3, 0 }; // invalid

4 Answers 4

3

The real difference here is that "abc" is a string literal of type char[], whereas {'a', 'b', 'c', 0} is not. You could easily use it to initialize a completely different type, for example:

struct s{
  char c;
  int i, j;
  float f;
} x = {'a', 'b', 'c', 0};

So when you write const char *b = { 'a' , 'b', 'c', '\0' };, the compiler picks the implicit conversion {'a'} -> 'a' and tries to initialize your pointer with that. This may or may not fail depending on the compiler and the actual value, for example many compilers would interpret const char *b = { '\0' }; as initializing b to a NULL pointer instead of an empty string as one could expect.

If you want to initialize the pointer to the address of an array (or any other type) created with list initialization, you should cast explicitly:

const char *b = (const char[]){'a', 'b', 'c', 0};
const int *a = (const int[]){'a', 'b', 'c', 0};
struct s *x = &(struct s){'a', 'b', 'c', 0};
Sign up to request clarification or add additional context in comments.

1 Comment

I believe this is the right answer. Editing mine would have probably been equivalent to copying your point. Therefore I deleted mine and I'm upvoting this one. Thanks for bringing this up.
1

In the first case you have a string literal which are arrays of char, it will be converted to a pointer to char in this context.

In the next two cases you are attempting to use list initialization to initialize a pointer which will attempt to convert the first element of the list to a pointer which generates a warning since neither a char or an int are pointers, the same way this would:

const char *b = 'a' ;

If you had valid pointers in the list it would work fine for the first element but would be ill-formed since you have more initializers than variables.

Comments

0

Array and pointer isn't the same thing.

const char *c = "abc";

Initialise pointer with address of string constant. Sting constant contained elsewhere (not on stack, usually special global constant area).

const char c[] = "abc";

Initialise array of chars with given characters (with contents of given string). This one would be on stack.

Comments

0

The first line is valid because the C standard allows for the creation of constant strings, because their length can be determined at compile time.

The same does not apply to pointers: the compiler can't decide whether it should allocate the memory for the array in the heap (just like a normal int[], for instance) or in regular memory, as in malloc().

If you initialize the array as:

   int a[] = { 1, 2, 3, 0 };

then it becomes valid, because now the compiler is sure that you want an array in the heap (temporary) memory, and it will be freed from memory after you leave the code section on which this is declared.

Comments

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.