clang和gcc与复合文字的不同行为

Alb*_*ymk 3 c gcc c99 clang compound-literals

最近遇到了复合文字,据我所知,以下是使用它的正确方法.幸运的是,它适用于ubuntu上的gcc和clang.

int main() {
  int *p = (int []) {1, 2};
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,我注意到使用复合文字的另一种方法,如下所示.感觉有点奇怪; 这只是数组初始化器.下面的代码用clang编译好,但是用gcc编译失败了array initialized from non-constant array expression.

int main() {
  int p[] = (int []) {1, 2};
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是故意还是什么?

ENV:

  • gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2
  • Ubuntu clang版本3.5-1ubuntu1(主干)(基于LLVM 3.5)

CMD:

  • gcc test.c
  • clang test.c

Pas*_*uoq 6

简短回答:Clang承认该程序使用了扩展名

接受你所写的内容,int p[] = (int []) {1, 2};是一个Clang扩展.GCC被允许拒绝它,因为它不是C99的一部分(C99标准引入了复合文字,可以作为参考).

事实上,我的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标准的一部分.

  • GCC似乎只对具有静态存储持续时间的对象实现这一点(`static int p [] =(int []){1,2};`).但Clang也为具有自动存储持续时间的应用程序实现了它.奇怪的.当它在Clang中实现时可能是一个疏忽,因为test/Sema/array-init.c中的测试用例不包括这样的情况. (3认同)