我无法弄清楚这一点。为什么编译:
typedef struct A {
int foo[3];
} a_t;
typedef struct B {
char tag;
a_t foo;
} b_t;
const a_t default_a = { { 1, 2, 3 } };
int
main(int argc, char **argv)
{
const b_t default_b = { 'A', default_a };
return 0;
}
这不是:
typedef struct A {
int foo[3];
} a_t;
typedef struct B {
char tag;
a_t foo;
} b_t;
const a_t default_a = { { 1, 2, 3 } };
const b_t default_b = { 'A', default_a };
int
main(int argc, char **argv)
{
return 0;
}
> gcc tp.c
tp.c:13:1 error: initializer element is not constant
tp.c:31:1 error: (near initialization for ...default_b.foo...)
唯一的变化是default_b声明的范围。为什么会有所不同?据我所知,要么它们都是有效的,要么都是错的。但是gcc(v4.7.3)接受第一个而不是第二个。这让我疯了。
[[edit]]奖励积分的后续问题:鉴于第二个程序不符合C标准,我如何以符合标准的方式完成同样的事情? IE:default_b的全局常量定义,包括default_a的值。
答案 0 :(得分:4)
C语言规范要求使用常量表达式初始化具有静态存储持续时间的对象。
在您的第一个代码段中,default_b
具有自动存储持续时间,而在第二个代码段中,由于它在文件范围内定义,因此具有静态存储持续时间。所以第二个程序违反了规则:
C11,6.7.9初始化
初始化程序中具有静态或。的对象的所有表达式 线程存储持续时间应为常量表达式或字符串 文字。
限定符const
不表示它是常量表达式,而应该将其视为只读。常量表达式可以在编译时进行评估:
6.6常量表达式
可以在翻译期间评估常量表达式而不是 运行时,因此可以在常量可以使用的任何地方使用 是