c - "Initializer element is not constant"将对象定义为函数的静态成员时

标签 c constants static-initialization

下面的代码可以毫无怨言地编译:

struct s {
    const int a;
};

static const struct s *s = &(const struct s) {
    .a = 5
};

int main(void) {
    (void) s;
    return 0;
}

但是,如果我们将 s 的定义移动到 main 的主体,即:

struct s {
    const int a;
};

int main(void) {
    static const struct s *s = &(const struct s) {
        .a = 5
    };
    (void) s;
    return 0;
}

我们得到错误:

error: initializer element is not constant
    static const struct s* s = &(const struct s) {
                               ^

因为在这两种情况下,我们都处理静态(即编译时)初始化,为什么第二个用例是非法的? 有什么方法可以使其在函数上下文中合法吗?

(我已经用 GCC 7.3.0 和 clang 6.0.0 检查过,它们都报告这是一个错误)

最佳答案

根据 C 2018 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 address constant, or…

根据 6.6 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…

然后,在 6.5.2.5(“复合文字”)5 中,我们有:

… If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

因此,在第一种情况下,复合文字是一个具有静态存储持续时间的对象,指向它的指针是一个地址常量。在第二种情况下,复合字面量是一个具有自动存储持续时间的对象,指向它的指针不是地址常量。

关于c - "Initializer element is not constant"将对象定义为函数的静态成员时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60190899/

相关文章:

c++ - 当工件是库且标志影响 C 或 C++ header 时,功能标志/切换

c - 有和没有辅助变量的变量交换——哪个更快?

php - 检查未定义的常量

java - 如何在 Java 中存储常量字符串数组

c++ - IBM XL C/C++ 是否提供 init_priority?

java - 在没有静态嵌套类的情况下按需初始化多个静态变量?

c - C中使用哈希表的符号表实现

c - 如何将 C 中带有数组的 while 循环转换为 ARM

c - 为什么 `const` 限定符在此初始化中被丢弃?

c++ - std::set 用作静态模板化成员变量