C99引入了结构的指定初始化器的概念。因此,例如,给定:
typedef struct {
int c;
char a;
float b;
} X;
我可以像这样初始化:X foo = {.a = '\1', .b = 2.0F, .c = 4};
并调用:printf("c = %d\na = %hhu\nb = %f", foo.c, foo.a, foo.b);
将输出:
c = 4
a = 1
b = 2.000000
这里提到这有分配给的“令人惊讶的行为” c
,然后a
再b
独立我指定的初始的顺序。
如果我具有以下功能,这将成为一个真正的问题:
int i = 0;
int f() {
return ++i;
}
int g() {
i += 2;
return i;
}
int h() {
i += 4;
return i;
}
我想这样初始化:X foo = {.a = (char)f(), .b = g(), .c = h()};
现在,当我这样做时:printf("c = %d\na = %hhu\nb = %f", foo.c, foo.a, foo.b);
我得到:
c = 4
a = 5
b = 7.000000
问题是没有警告我的初始化顺序未得到遵守。是否有警告或我可以启用的功能?
[现场示例]
...没有警告我的初始化顺序未得到遵守。
特定的初始化顺序是基于标准中规定以外的期望。(如评论中指出)
C99第6.7.9节,第23页:23对初始化列表表达式的求值是不确定地相互关联的,因此未指定发生任何副作用的顺序。[强调我的]
因此,除了未定义(或未指定)行为外,这里没有问题。与其他C行为非常相似,例如函数参数的求值顺序不明确。
EDIT
C99可以这样说:
从C99§6.5.2.2p10起:
未指定函数自变量的求值顺序,未指定函数指定符,实际自变量和实际自变量内的子表达式的求值顺序,但在实际调用之前有一个序列点。
[强调我的]
您更喜欢警告(您说得好,+ 1)是另一回事。我不确定在C / C ++语言中为-每个-未定义--行为提供警告会多么实用。
有趣的是,在此讨论中,一些陈述的假设/观点为何C ++标准不包括指定的初始化程序。(还)...
... C ++更感兴趣的是将灵活性放在类型设计者的一边,因此设计者可以使正确使用类型的操作变得容易,而错误使用则更加困难。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句