【发布时间】:2021-09-16 00:35:15
【问题描述】:
在最新版本的 gcc(或 clang)中使用 -std=c17 -pedantic-errors -Wall -Wextra 编译此代码时
static const int y = 1;
static int x = y;
然后我没有收到编译器诊断消息,即使我相当确定这不是有效的 C 而是违反约束。我们可以通过查看 C17 6.7.9/4 来证明它是不合格的:
约束
...
具有静态或线程存储持续时间的对象的初始化程序中的所有表达式都应为常量表达式或字符串文字。
然后是关于常量表达式的定义,本例为整数常量表达式(6.6):
整数常量表达式应该是整数类型,并且只能有整数常量、枚举常量、字符常量、结果为整数常量的 sizeof 表达式、_Alignof 表达式和浮点常量的操作数。类型转换的直接操作数。
最后是关于整数常量的定义(6.4.4.1/2):
整数常量以数字开头,但没有句点或指数部分。它可能有一个指定其基数的前缀和一个指定其类型的后缀。
因此,const int 变量不是整数常量,也不是整数常量表达式。因此不是有效的初始化程序。这已经在之前讨论过(例如here),我认为已经确定这是不合格的。但是,我的问题是:
为什么 gcc 即使在严格模式下也选择不合规?
clang 显然一直是不合规的,但是 gcc 从 7.3 版的合规变成了 8.0 及更高版本的不合规。 gcc 7.3 及更早版本即使在没有-pedantic-errors 的默认模式下也会给出“错误:初始化元素不是常量”。
似乎已经对这条信息做出了某种积极、有意识的决定。为什么它在 gcc 中被完全删除,为什么他们没有在严格模式下编译时保持原样-std=c17 -pedantic-errors?
【问题讨论】:
-
如果有人能找到 clang 选择不合规的理由,那也很有趣。不过,我将这个问题专门留给 gcc,以避免一次问两个问题。
-
@jdm 在 KamilCuk 提出的问题中发表了评论,该评论链接到这个 gcc 错误:gcc.gnu.org/bugzilla/show_bug.cgi?id=69960,我认为通过记录讨论来回答您的问题。
-
@AlexLop。不,这没有回答“为什么 gcc 即使在严格模式下也选择不合规?”的问题。如问题中所述,我们已经确定这是不合规的,这不是我要问的。
-
@PaulHankin 不是真的,这只是各种不那么混乱的随机 cmets。编译器不允许静默忽略约束违规。
标签: c gcc initializer static-initialization