【问题标题】:Why would GCC/Clang accept const qualified object as initializer for object with static storage duration?为什么 GCC/Clang 会接受 const 限定对象作为具有静态存储持续时间的对象的初始化程序?
【发布时间】:2020-03-22 17:01:14
【问题描述】:

据我所知,ISO C 标准对于 C11 中具有静态存储持续时间的对象的初始化程序是严格的 6.7.9 Initialization

具有静态或线程存储持续时间的对象的初始化程序中的所有表达式都应为常量表达式或字符串文字。

但是 GCC/Clang 都接受了以下代码:

const int i = 3; // const here should not make i a constant expression
static int j = i;

即使使用-Wall -Wextra -Werror -pedantic-errors,上面的编译器也没有给我任何抱怨。

但是,这些编译器确实意识到i 不是一个常量表达式。比如 Clang 给我的:

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

以下代码:

const size_t sz = 3;
static int a[sz];

我这里有什么问题吗?

【问题讨论】:

  • 编译器扩展
  • @Achel 因为标准并没有使其成为一体。如果您尝试使用i 作为static 数组的大小,您的代码将被拒绝。
  • @klutt 我也是这么想的。但是如果需要常量表达式的其他场景涉及i,这些编译器会抱怨。

标签: c static constants


【解决方案1】:

你没有错过任何东西,它确实不是一个严格符合 C 程序的程序,并且是编译器方面的一个不符合标准的行为。这很可能是因为 GCC 和 Clang 也是 C++ 的编译器套件。在 C++ 中,ij 的有效初始化程序。

然而值得注意的是,尽管编译器可以自行决定翻译不符合标准的 C 程序,但他们仍必须根据 C11 5.1.1.3 p1 发布关于不符合标准的诊断:

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

即使我们接受该行为作为扩展,GCC 和 Clang 不发出诊断的事实也是它们双方的一致性错误。

【讨论】:

  • 它不是一个不符合标准的编译器,因为还有一个条款,编译器可以接受除强制之外的其他形式的常量表达式
猜你喜欢
  • 2021-09-16
  • 2016-11-06
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
相关资源
最近更新 更多