最近遇到过复合文字,据我了解,以下是使用它的正确方法。幸运的是,它适用于ubuntu上的gcc和clang。
int main() {
int *p = (int []) {1, 2};
return 0;
}
但是,我注意到使用复合文字的另一种方法,如下所示。感觉有点奇怪;这只是数组初始化器。以下代码使用clang编译良好,但使用gcc array initialized from non-constant array expression
失败。
int main() {
int p[] = (int []) {1, 2};
return 0;
}
这是故意还是什么?
ENV:
CMD:
答案 0 :(得分:6)
接受你所写的内容int p[] = (int []) {1, 2};
,是一个Clang扩展。 GCC被允许拒绝它,因为它不是C99的一部分(C99 standard引入的复合文字,可以用作参考)。
事实上,我的Clang版本可以在你的程序上发出警告。有趣的是,它将您的行称为“GNU扩展”:
~ $ 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
第int p[] = (int []) {1, 2};
行是一个声明。它应该遵循第6.7节中给出的语法:
6.7声明
语法
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
所有这些都取决于初始化程序的定义,可以在6.7.8中找到:
6.7.8初始化
<强>语法强>
1
initializer: assignment-expression { initializer-list } { initializer-list , } …...
12本子条款的其余部分涉及具有聚合或联合类型的对象的初始值设定项。
...
16否则,具有聚合或联合类型的对象的初始值设定项应为括号内的元素或命名成员的初始值设定项列表。
6.7.8:16的重点是我的。基本上,这是您的程序不满足的C99标准的一部分。
答案 1 :(得分:-1)
复合文字在C99和C ++中有不同的行为。
在C ++中,它只有一个表达式存储持续时间,而不是自动持续时间。如果这是在C ++模式下编译的,那么它将无法工作,因为复合文字对象在表达式完成后消失。
这可以解释@ cremno关于静态存储持续时间和自动存储持续时间的描述。