gpt4 book ai didi

c - 为什么 C 中的静态初始化表达式不能使用常量数组的元素?

转载 作者:太空狗 更新时间:2023-10-29 15:25:31 24 4
gpt4 key购买 nike

以下(公认的人为设计的)C 程序无法编译:

int main() {
const int array[] = {1,2,3};
static int x = array[1];
}

用gcc(或微软的CL.EXE)编译上述C源文件时,出现如下错误:

error: initializer element is not constant
static int x = array[1];
^

如此简单直观的语法当然有用,所以这似乎应该是合法的,但显然不是。当然,我不是唯一对这个明显愚蠢的限制感到沮丧的人。我不明白为什么不允许这样做——C 语言试图通过使这种有用的语法成为非法来避免什么问题?

这似乎与编译器为初始化生成汇编代码的方式有关,因为如果删除“static”关键字(这样变量“x”就在堆栈上),那么它编译正常。

然而,另一件奇怪的事情是它在 C++ 中编译良好(即使使用 static 关键字),但在 C 中却不行。因此,C++ 编译器似乎能够生成执行此类初始化所需的汇编代码。

编辑:感谢 Davislor——为了安抚当时的 SO 权力,我会寻求以下类型的事实信息来回答这个问题:

  1. 是否有任何支持这些语义的遗留代码会被破坏?

  2. 是否曾向标准委员会正式提出这些语义?

  3. 有没有人给出拒绝允许这些语义的理由?

最佳答案

具有静态存储持续时间的对象(读取:在文件范围或使用 static 关键字声明的变量)必须由编译时常量初始化。

关于初始化状态的 C 标准第 6.7.9 节:

4 All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

关于常量表达式的第 6.6 节指出:

7 More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:

  • an arithmetic constant expression,
  • a null pointer constant,
  • an address constant, or
  • an address constant for a complete object type plus or minus an integer constant expression.

8 An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and _Alignof expressions. Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof or _Alignof operator.

9 An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; it shall be created explicitly using the unary & operator or an integer constant cast to pointer type, or implicitly by the use of an expression of array or function type. The array-subscript [] and member-access . and -> operators, the address & and indirection * unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators.

根据上述定义,const 变量不符合常量表达式的条件,因此不能用于初始化static 对象。另一方面,C++ 确实const 变量视为真正的常量,因此允许它们初始化静态对象。

关于c - 为什么 C 中的静态初始化表达式不能使用常量数组的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51065612/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com