Clang 无法在 C89 模式下对非常量数组初始值设定项抛出错误

标签 c clang c89

这是 Clang 中的错误吗?以下代码:

#include <stdio.h>

int main(void)
{
    int foo = 42;
    int bar[1] = { foo };
    printf("%d\n", bar[0]);
    return 0;
}

编译良好使用:

clang -Wall -Wextra -Werror -pedantic -pedantic-errors -std=c89 -o foo foo.c

我认为它不应该编译,因为 bar[] 的初始化列表包含一个表达式 foo,它不是编译时常量。事实上,如果我使用 gcc 而不是 clang,我会得到预期的结果:

$ gcc -Wall -Wextra -Werror -pedantic -pedantic-errors -std=c89 -o foo foo.c
foo.c: In function ‘main’:
foo.c:6: error: initializer element is not computable at load time

This question and its accepted answer , 以及 this C89 description 的摘录建议 GCC 是对的,Clang 是错的:

The expressions in initializer for static object, or for aggregate or union, must be constant expressions.

我的 clang 版本是:

$ clang -v
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin11.4.2

我注意到的一件事是 opensource.apple.com 上出现的最新版本的 clang,即。 e. clang 425.0.24,仅比我的 clang 早 4 个次要修订版,并且它确实有数组初始值设定项的单元测试。但是,除非我遗漏了什么,否则不会测试具有非常量表达式的 block 作用域自动数组的初始化(仅测试 block 作用域静态数组和全局数组)。 Here's the test file I found .

那么,这是怎么回事?

最佳答案

这看起来像是旧版本 clang 中的一个错误,因为 3.5 版本给我以下代码的警告:

warning: initializer for aggregate is not a compile-time constant [-Wc99-extensions]
int bar[1] = { foo };
             ^~~~~~~

还有你的编译选项错误 ( see it live )。

缺少公开的 C89 草案,我发现 gcc 有一个关于 Non-Constant Initializers 的部分其中说:

As in standard C++ and ISO C99, the elements of an aggregate initializer for an automatic variable are not required to be constant expressions in GNU C.

这证实了在 C99 之前,它们曾经被要求是常量表达式

正如 tab 告诉我们的那样,C89 标准的相关引述来自 3.5.7 部分并说:

All the expressions in an initializer for an object that has static storage duration or in an initializer list for an object that has aggregate or union type shall be constant expressions.

关于Clang 无法在 C89 模式下对非常量数组初始值设定项抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21148232/

相关文章:

c - GLFW GLSL OPENGL问题

c - 直方图进入无限循环

c - 我需要在 LLVM 中实现什么才能使 Clang 为自定义架构生成 IR?

clang - 在哪里可以找到clang -OX的优化顺序?

c - printf 是否需要 %zu 说明符?

c - c90 程序中的 exc_bad_access(code=1 address=0x68)

CUDA __global__ 函数未调用

c - 将命令行参数作为一个大字符串获取

c++ - 如何创建 C API 到 C++ 函数

windows - Clang 启动慢(使用 MinGW)