我偶然发现了一些我在网上找不到任何信息的怪异行为。如果我像这样初始化一个布尔数组:
bool condition[10] = {true,[5]=true};
我得到了我期望的输出,第一和第六个值为true,而其他值为false。但是,如果我写下以下片段:
bool condition[10] = {true,condition[5]=true};
我得到第一,第二和第六个值为真。我认为这是某种未定义的行为,但我想让一个比我更有知识的人向我解释发生了什么。
我正在编译额外的警告标志,使用GCC和“-std = gnu99”,我没有收到任何错误。
答案 0 :(得分:18)
(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};
是否在condition[5] = true
初始化数组成员之前或之后完成0
评估。
编辑:在缺陷报告#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)的结果用于初始化[0]。
答案 1 :(得分:10)
这是一个不错的小谜题。我想我们得到了它,但更多的解释可能会有所帮助。我认为条件[5] = true是不是指定的初始化程序。它是一个表达式,像往常一样评估为真。由于该表达式位于第二个点,因此true被赋值给条件[1]。此外,作为表达式的副作用,条件[5]设置为true。