c - 不是常量初始化元素?

标签 c gcc compiler-errors compiler-construction semantics

我在为我的编译器类(class)做语义分析时遇到了一个令人困惑的案例。

#include <stdio.h>

int a = "abcd"[2];

int main()
{
    char b = "abcd"[2];

    printf("%d\n%c\n", a, b);

    return 0;
}

GCC 为变量“a”提示“错误:初始化元素不是常量”。

为什么?

最佳答案

C 语言要求全局变量的初始值设定项是常量表达式。这背后的动机是编译器能够在编译时计算表达式并将计算值写入生成的目标文件。

The C standard为什么是常量表达式提供了特定规则:

  1. An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator .
  2. 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.

如您所见,所有情况都不包括数组访问表达式或指针取消引用。所以 "abcd"[2] 不符合标准的常量表达式。

现在标准还说:

  1. An implementation may accept other forms of constant expressions.

因此允许"abcd"[1]作为常量表达式并不违反标准,但也不能保证允许。

因此是否允许在编译器中使用它取决于您。无论哪种方式,它都将符合标准(尽管允许它做更多的工作,因为您需要在 isConstantExpression 检查中使用另一个案例,并且您实际上需要能够在编译时评估表达式,所以我会去不允许它)。

关于c - 不是常量初始化元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43072204/

相关文章:

c# - C 和 C# 中的字符串解析器

c++ - 如何在取消引用空指针时创建错误?

C++ 编译器不应用模板

php - JavaScript奇怪的错误:“意外的')'”

c - C 编程中的二维字符数组

c - 在函数中分配内存后为结构赋值

c - 如何一次重命名多个变量名称 (c/c++)

c++ - 如何在 Bootstrap 期间在 gcc 二进制文件上设置 rpath?

c - C/C++ 优化如何影响 volatile 变量?

compiler-errors - go 和 gwan 未使用的变量