为什么GCC/Clang会接受const限定对象作为具有静态存储持续时间的对象的初始值设定项?

为什么GCC/Clang会接受const限定对象作为具有静态存储持续时间的对象的初始值设定项?,c,static,constants,C,Static,Constants,据我所知,ISO C标准对C116.7.9中具有静态存储持续时间的对象的初始值设定非常严格 具有静态或线程存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字 但GCC/Clang均接受以下代码: 常数int i=3;//这里的常量不应使i成为常量表达式 静态int j=i; 即使有-Wall-Wextra-Werror-pedantic错误,上面的编译器也没有给我任何抱怨 然而,这些编译器确实意识到我不是一个常量表达式。例如,Clang给了我: 错误:静态数组的大小必须是整

据我所知,ISO C标准对C116.7.9中具有静态存储持续时间的对象的初始值设定非常严格

具有静态或线程存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字

但GCC/Clang均接受以下代码:

常数int i=3;//这里的常量不应使i成为常量表达式 静态int j=i; 即使有-Wall-Wextra-Werror-pedantic错误,上面的编译器也没有给我任何抱怨

然而,这些编译器确实意识到我不是一个常量表达式。例如,Clang给了我:

错误:静态数组的大小必须是整数常量表达式

对于以下代码:

const size_t sz=3; 静态整数a[sz];
我这里有什么地方出错吗?

您没有遗漏任何内容,它确实是一个不符合要求的C程序,而且编译器的行为也不符合要求。这很可能是因为GCC和Clang都是C++的编译器套件。在C++中,i是J.

的有效初始化器。 然而,值得注意的是,尽管编译器可以自由地翻译不符合要求的C程序,但他们仍然必须根据C115.1.1.3 p1:

一致性实施应产生至少一个诊断结果 以实现定义的方式标识的消息,如果 预处理翻译单元或翻译单元包含 违反任何语法规则或约束,即使行为是 还显式指定为未定义或实现定义。 在其他情况下不需要生成诊断消息


即使我们接受该行为作为扩展,GCC和Clang没有发出诊断的事实在它们的两个部分上都是一致性错误。

您没有遗漏任何东西,它确实是一个不一致的C程序,并且是编译器部分的不一致行为。这很可能是因为GCC和Clang都是C++的编译器套件。在C++中,i是J.

的有效初始化器。 然而,值得注意的是,尽管编译器可以自由地翻译不符合要求的C程序,但他们仍然必须根据C115.1.1.3 p1:

一致性实施应产生至少一个诊断结果 以实现定义的方式标识的消息,如果 预处理翻译单元或翻译单元包含 违反任何语法规则或约束,即使行为是 还显式指定为未定义或实现定义。 在其他情况下不需要生成诊断消息


即使我们接受该行为作为扩展,GCC和Clang没有发出诊断的事实也是它们两个部分的一致性错误。

Compilerextensions@Achel因为标准没有把它变成一个。如果您尝试使用i作为静态数组的大小,您的代码将被拒绝。@klutt我也这么认为。但如果其他需要常量表达式的场景涉及i.Related:Compiler,这些编译器会抱怨extensions@Achel因为标准没有把它变成一个。如果您尝试使用i作为静态数组的大小,您的代码将被拒绝。@klutt我也这么认为。但是,如果其他需要常量表达式的场景涉及i.相关的: