“初始化元素不是常量”,在C99的静态结构上使用指定的初始值设定项

时间:2013-12-21 14:25:07

标签: c c99

有人可以解释这种行为吗?

使用编译器标志std=c99我收到以下错误:

    对于b1,
  • “初始化元素不是常数”。
  • “'之前的预期表达'。'令牌“for b2
  • b3没问题。

不使用-std=c99时,所有行都可以。 当不使用静态b1是好的。 我正在使用GCC。

typedef struct A_tag {
    int v;
    int w;
} A;

typedef struct B_tag {
    A super;
    int x;
    int y;
} B;

void test(){
static B b1 = ((B){.super={.v=100}, .x=10});
static B b2 = ({.super={.v=100}, .x=10});
static B b3 = {.super={.v=100}, .x=10};
}

3 个答案:

答案 0 :(得分:7)

(B){.super={.v=100}, .x=10}不是“演员”,但作为一个整体,这是一个“复合文字”,一个只存在于相应表达式内的临时对象(基本上)。由于这不是一个常数而是一个临时对象,按照标准你不能用它初始化。

答案 1 :(得分:1)

如上所述,这是一个“复合文字”。它是否可以用于初始化实际上是实现定义的,IMO。 C11标准在[6.7.9§4]中说“具有静态或线程存储持续时间的对象的初始值设定项中的表达式应为常量表达式或字符串文字”。然后在[6.6§7]中列出了常量表达式,[6.6§10]它允许实现“接受其他形式的常量表达式”。

由于“复合文字”在定义上是不变的,因此应该可以将其用于初始化,尽管标准没有明确说明。 (许多编译器都接受它。)

答案 2 :(得分:1)

阅读C11标准(实际上是N1570是较晚的草案),您会看到静态存储持续时间的对象的初始化程序规则与自动存储持续时间的对象的规则不同。

在我阅读本文时,复合文字只能用于自动存储持续时间的对象的初始化程序。 6.7.9第13段允许使用它们。