在C语言中初始化布尔数组

22

我遇到了一些奇怪的行为,但我在网上找不到任何信息。如果我像这样初始化一个布尔数组:

 bool condition[10] = {true,[5]=true};

我得到了我期望的输出,第一个和第六个值是 true,而其他的值是 false。但如果我写以下代码片段:

 bool condition[10] = {true,condition[5]=true};

我得到了第一个、第二个和第六个值为true。我认为这是某种未定义的行为,但我希望有比我更有知识的人能解释一下发生了什么。

我正在使用GCC编译器和“-std = gnu99”编译选项,并使用额外的警告标志,但我没有收到任何错误消息。


表达式的值可以在C99中用作初始化器。此时condition[5]也可用。 - BLUEPIXY
1
是啊,但它不应该只翻转第二个值并停止吗?为什么它会在其上方翻转第六个或我指定的任何值(就像我正在键入{true,condition [5],[5] = true}一样)? - user3533671
5
你明确地将条件[5]设置为true,这就是它为什么为true的原因。你还通过使用true值进行初始化来将条件[1]设置为true。 "对我来说,看起来好像IF和ELSE都同时执行了。" -- 不,你没有清晰地思考这个问题。正如ouah所解释的那样,条件[5]的设置可以发生在数组初始化之后(就像你的情况),也可以不会... 这在标准中没有具体说明。 - Jim Balter
1
我明白了,所以基本上condition[5]=true是将第一个值设置为true,然后执行它应该执行的操作。谢谢,我无法理解它,我想我需要喝咖啡才能正常工作! - user3533671
3
condition[5]=true 是一次赋值操作。它将值 true 赋给了 condition[5]。同时,它产生了值 true,用于初始化了 condition[1] - Keith Thompson
显示剩余5条评论
2个回答

18

C说:

(C11,6.7.9p23) "初始化列表表达式的求值在彼此之间是不确定顺序的,因此任何副作用发生的顺序是未指定的。"

而在C99中:

(C99,6.7.8p23) "在初始化列表表达式中,任何副作用发生的顺序都是未指定的。"

这意味着声明:

    bool condition[10] = {true,condition[5]=true};

可以有相同的行为:

    bool condition[10] = {true, 1};

或者作为

    bool condition[10] = {true, 1, [5] = true};

数组成员的0初始化是在condition [5] = true评估之前还是之后完成的,需要视情况而定。

编辑: 在缺陷报告#208中存在未指定的数组元素初始化顺序情况。该情况不同,因为在DR示例中,存在单个元素的两个初始化器。

http://www.open-std.org/jtc1/sc22/wg14/www/docs/9899tc1/n32074.htm

int a [2] = { f (0), f (1), [0] = f (2) };

WG14的意图是,在初始化a时可能会调用f(0),但不一定要调用。如果进行调用,则f(0)和f(2)发生的顺序是未指定的(f(1)相对于这两个的顺序也是如此)。无论是否进行调用,f(2)的结果都用于初始化a [0]。


1
我认为你的引用只适用于所有初始化程序之间的副作用,而不适用于这些效果相对于初始化本身的顺序? - Kerrek SB
4
你能猜测一下condition[10] = { true, condition[0]=false }的意思吗? - Jim Balter
2
我认为@KerrekSB是正确的:无法确定先评估true还是condition[5]=true,但由于它们互不影响,所以这并不重要。 [0]将被设置为true[1]将被设置为condition[5]=true的结果,并且由于分配作为表达式具有分配的值,因此[5]=true发生在[1]=true之前,而[0]=true在此之前或之后发生。 - glglgl
2
@JimBalter 对的,在这种情况下,结果可能是未指定的。 - glglgl
“同意”--但你说它很接近;实际上并不是,因为在这种情况下没有明确设置a的元素...[0] = expr不像或接近a[0] = expr。在DR中,a [0]有两个初始化程序,后一个覆盖了前一个。在这里,每个[0]和[1]都只有一个初始化程序,而[5]没有。 - Jim Balter
显示剩余16条评论

10

这是一个不错的小谜题。我认为Ouah已经解决了它,但更多的解释可能会有所帮助。我认为condition[5]=true 不是 指定的初始化程序。它是一个表达式,像往常一样求值为true。由于该表达式在第二个位置上,true被分配给了condition[1]。此外,作为表达式的副作用,condition[5]也被设置为true。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接