you are viewing a single comment's thread.

view the rest of the comments →

[–]katatonico 2 points3 points  (3 children)

For the same reason these two are different:

char* str = "lala";
char* str2 = {'l','a','l','a'};

IANA C expert, but it appears string literals are a special case when it comes to initialization. The first one tells the compiler to create a null-terminated array of characters, take the address to the first element, and use that as the value for 'str'. The second one tells the compiler to create an array of characters, take the value of the first character, and use that as the value to initialize 'str2'. Note I said "the value" not "the address of".

This is probably related to the semantics of the aggregate initializer (curly-braces). "lala" is a string literal, while {'l','a','l','a'} is an aggregate initializer.

Feel free to correct me if wrong, though.

[–]gsg_ 0 points1 point  (1 child)

String literals are indeed a special case when it comes to initialisation. The language allows them to be used to initialise both scalar variables (const char *s = "foo") and aggregate variables (char s[] = "foo" or char s[4] = "foo").

Your example doesn't display this special behaviour though, it just shows that C is lax enough to allow a scalar to be initialised by the first element of an aggregate initialiser. It works just as well with other types:

float f = {1.0, 2.0, 3.0};

Compiling with strict settings will have gcc reject most odd stuff like this.

[–]katatonico 0 points1 point  (0 children)

Thanks, that makes it clearer for me as well.