Please consider the following absurd but compiling code:
int main(int argc, char *argv[]) {
void *a, *b, *c, *d;
void *the_good_array[] = { a, b, c, d };
void *the_bad_array = { a, b, c, d };
return 0;
}
I accidentally produced something similar and, to my astonishment, it fully compiles.
{ a, b, c, d }
supposed to mean as an initializer for a non array? Without the braces, I would understand it's an accidental use of the ,
operator resulting in the value of the last element (d
). But, braces? What are they supposed to mean here?If possible, please refer to the C standard when answering.
Edit 1: Compiles with both:
gcc -std=iso9899:1990 /tmp/bad_array.c # gcc (Debian 12.2.0-14)`
clang -std=iso9899:1990 /tmp/bad_array.c # Debian clang version 14.0.6
Edit 2: Apparently
int i = { 0 };
is perfectly valid C.
I would like to know why but don't have the standard to read it.
What is { a, b, c, d } supposed to mean as an initializer for a non array?
Having multiple intializer elements for single object is a constraint violation. N2176 (C17 standard draft) §6.7.9 Initialization:
Constraints
- No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
In this case it's depends on compiler what happens.
Why does it compile?
C compilers take backwards compatibility quite seriosly, and will accept a lot of code that would be considered invalid nowadays.
But, braces? What are they supposed to mean here?
Braces are allowed allowed even around single expression:
Syntax
- initializer:
- assignment-expression
- { initializer-list }
- { initializer-list , }
- initializer-list:
- designationopt initializer
- initializer-list , designationopt initializer
...
With rules above, initializer
can after a few steps be expanded to { assignment-expression }
.