Question

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
Was it helpful?

Solution 2

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.

OTHER TIPS

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};

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top