最近遇到复合字面量,据我了解,以下是正确的使用方法。幸运的是,它适用于 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;
}

这是故意的还是什么?

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

  • 指令:
  • gcc test.c
  • clang test.c
  • 最佳答案

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

    接受你写的 int p[] = (int []) {1, 2}; ,是一个 Clang 扩展。允许 GCC 拒绝它,因为它不是 C99 的一部分(C99 standard 引入了复合文字,可以用作引用)。

    事实上,我的 Clang 版本可以在你的程序中发出警告。有趣的是,它将您的线路称为“GNU 扩展”:

    ~ $ clang -std=c99 -pedantic t.c
    t.c:2:7: 警告:从复合初始化“int []”类型的数组
    “int [2]”类型的文字是 GNU 扩展
    [-Wgnu-compound-literal-initializer]
    int p[] = (int []) {1, 2};
    ^ ~~~~~~~~~~~~~~~
    已生成 1 个警告。
    ~ $ clang -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.8 中找到:



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

    关于clang 和 gcc 具有复合文字的不同行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27734247/

    10-15 06:05