简短回答:Clang 承认该程序使用了扩展
接受你写的int p[] = (int []) {1, 2};
,是一个 Clang 扩展。允许 GCC 拒绝它,因为它不是 C99 的一部分(C99 标准引入了复合文字,可以用作参考)。
事实上,我的 Clang 版本可以对你的程序发出警告。有趣的是,它将您的行称为“GNU 扩展”:
~ $ clang -std=c99 -pedantic tc
tc:2:7: 警告:从复合中初始化类型为“int []”的数组
'int [2]' 类型的文字是 GNU 扩展
[-Wgnu-compound-literal-initializer]
int p[] = (int []) {1, 2};
^ ~~~~~~~~~~~~~~~
生成 1 个警告。
~ $ 铿锵 -v
Apple LLVM 5.1 版(clang-503.0.40)(基于 LLVM 3.4svn)
目标:x86_64-apple-darwin13.4.0
线程模型:posix
长答案
该行int p[] = (int []) {1, 2};
是一个声明。它应该遵循第 6.7 节中给出的语法:
6.7 声明
句法
1
宣言:
声明说明符 init-declarator-list opt ;
声明说明符:
存储类说明符 声明说明符opt
类型说明符 声明说明符opt
类型限定符 声明说明符opt
函数说明符 声明说明符opt
初始化声明器列表:
初始化声明器
初始化声明器列表,初始化声明器
初始化声明器:
声明者
声明器 = 初始化器
一切都取决于initializer的定义,可以在 6.7.8 中找到:
6.7.8 初始化
句法
1
初始化器:
赋值表达式
{初始化列表}
{初始化列表,}
…</pre>
…</p>
12 本小节的其余部分处理具有聚合或联合类型的对象的初始值设定项。
…</p>
16 否则,具有聚合或联合类型的对象的初始化程序应为元素或命名成员的初始化程序的大括号括起来的列表。
6.7.8:16 中的重点是我的。基本上,这是您的程序不满足的 C99 标准的一部分。