Came across compound literal recently, and as far as I understand it, the following is the correct way of using it. Fortunately, it works both with gcc and clang on ubuntu.
int main() {
int *p = (int []) {1, 2};
return 0;
}
However, I notice another way of using compound literal, shown below. It feels a bit weird; this is just array initializer. The following code compiles fine with clang, but failed with gcc, array initialized from non-constant array expression
.
int main() {
int p[] = (int []) {1, 2};
return 0;
}
Is this intentional or what?
ENV:
CMD:
Accepting what you wrote, int p[] = (int []) {1, 2};
, is a Clang extension. GCC is allowed to reject it, because it is not part of C99 (the C99 standard introduced compound literals and can be used as reference).
In fact, my version of Clang can be made to emit a warning on your program. It is funny that it calls your line a “GNU extension”:
~ $ clang -std=c99 -pedantic t.c t.c:2:7: warning: initialization of an array of type 'int []' from a compound literal of type 'int [2]' is a GNU extension [-Wgnu-compound-literal-initializer] int p[] = (int []) {1, 2}; ^ ~~~~~~~~~~~~~~~ 1 warning generated. ~ $ clang -v Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.4.0 Thread model: posix
The line int p[] = (int []) {1, 2};
is a declaration. It should follow the syntax given in clause 6.7:
6.7 Declarations
Syntax
1
declaration: declaration-specifiers init-declarator-listopt ; declaration-specifiers: storage-class-specifier declaration-specifiersopt type-specifier declaration-specifiersopt type-qualifier declaration-specifiersopt function-specifier declaration-specifiersopt init-declarator-list: init-declarator init-declarator-list , init-declarator init-declarator: declarator declarator = initializer
All lies on the definition of initializer, which can be found in 6.7.8:
6.7.8 Initialization
Syntax
1
initializer: assignment-expression { initializer-list } { initializer-list , } ……
12 The rest of this subclause deals with initializers for objects that have aggregate or union type.
…
16 Otherwise, the initializer for an object that has aggregate or union type shall be a brace-enclosed list of initializers for the elements or named members.
The emphasis in 6.7.8:16 is mine. Basically, this is the part of the C99 standard that your program does not satisfy.