Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C99静态结构上的指定初始值设定项“初始值设定项元素不是常量”_C_C99 - Fatal编程技术网

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

使用C99静态结构上的指定初始值设定项“初始值设定项元素不是常量”,c,c99,C,C99,有人能解释这种行为吗 使用编译器标志std=c99,我得到以下错误: b1的初始值设定项元素不是常量。 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(){ stat

有人能解释这种行为吗

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

b1的初始值设定项元素不是常量。 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};
}

B{.super={.v=100},.x=10}不是强制转换,但作为一个整体,这是一个复合文本,一个临时对象,基本上只存在于相应的表达式中。因为这不是一个常量,而是一个临时对象,按照标准,你不能用它初始化。

B{.super={.v=100},.x=10}不是强制转换,但作为一个整体,这是一个复合文本,一个临时对象,基本上只存在于相应的表达式中。因为这不是一个常量,而是一个临时对象,按照标准,您不能用它初始化。

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


由于复合文字的定义是常量,因此应该可以将其用于初始化,尽管标准没有明确说明这一点。许多编译器都接受它。

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


由于复合文字的定义是常量,因此应该可以将其用于初始化,尽管标准没有明确说明这一点。许多编译器确实接受了这一点。

阅读C11标准N1570(这是一个最新的草案),您会发现静态存储持续时间对象的初始化规则与自动存储持续时间对象的初始化规则不同


正如我所读到的,复合文本只能用于自动存储持续时间的对象的初始值设定项。6.7.9第13段允许它们。

阅读C11标准N1570(这是一个最新草案),您会发现静态存储持续时间对象的初始化规则与自动存储持续时间对象的初始化规则不同


正如我所读到的,复合文本只能用于自动存储持续时间的对象的初始值设定项。6.7.9第13段允许它们。

为什么在初始化之前使用B?@JoachimPileborg您的陈述不正确,它与C99有关。错误也会在-std=gnu99时出现,但在-std=c89或-std=gnu89时消失。令人惊讶的是,clang接受带C99标志和不带C99标志的代码。我需要这些括号,因为我想在宏中使用初始值设定项。目前的解决方法:定义保护。。。弗吉尼亚州_ARGS@Dill; 从初始值设定项的开头删除B,它将正常工作。“我想没必要投,”哈克斯说,“当然。我不知道为什么演员会出现在那里,在代码里。我只是移植到C99。我只是不明白为什么这个强制转换会有问题,并且使初始化器不是常量。为什么在初始化之前是B?@JoachimPileborg你的陈述不正确,它与C99有关。错误也会在-std=gnu99时出现,但在-std=c89或-std=gnu89时消失。令人惊讶的是,clang接受带C99标志和不带C99标志的代码。我需要这些括号,因为我想在宏中使用初始值设定项。目前的解决方法:定义保护。。。弗吉尼亚州_ARGS@Dill; 从初始值设定项的开头删除B,它将正常工作。“我想没必要投,”哈克斯说,“当然。我不知道为什么演员会出现在那里,在代码里。我只是移植到C99。我只是不明白为什么这个强制转换应该是一个问题,并且使初始值设定项不是常量。nice:intvv=B{.super={.v=100},.x=10}.v;nice:intvv=B{.super={.v=100}.x=10}.v;