繁体   English   中英

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

[英]clang and gcc different behavior with compound literal

最近遇到了复合文字,据我所知,以下是使用它的正确方法。 幸运的是,它适用于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:

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

CMD:

  • gcc test.c
  • clang test.c

简短回答: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

  宣言:\n     declaration-specifiers init-declarator-list opt ;\n\n 声明-符:\n     存储类说明符声明,符选择\n     type-specifier declaration-specifiers opt\n     type-qualifier声明 - 说明符opt\n     function-specifier declaration-specifiers opt\n\n 初始化声明符列表:\n     初始化声明符\n     init-declarator-list,init-declarator\n\n 初始化声明符:\n     声明符\n     declarator =初始化器 

所有这些都取决于初始化程序的定义,可以在6.7.8中找到:

6.7.8初始化

句法

1

  初始化:\n     赋值表达式\n     {initializer-list}\n     {initializer-list,}\n ... 

...

12本子条款的其余部分涉及具有聚合或联合类型的对象的初始值设定项。

...

16否则,具有聚合或联合类型的对象的初始值设定项应该是元素或命名成员的大括号括起来的初始值设定项列表

6.7.8:16的重点是我的。 基本上,这是您的程序不满足的C99标准的一部分。

复合文字在C99和C ++中具有不同的行为。

在C ++中,它只有一个表达式存储持续时间,而不是自动持续时间。 如果这是在C ++模式下编译的,那么它将无法工作,因为复合文字对象在表达式完成后消失。

这可能解释了@ cremno关于静态存储持续时间和自动存储持续时间的描述。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM