可能是重复的问题:
数组初始化,引用之前的元素是否安全?
我想知道在C/C++标准中这样的初始化是否安全:
int a = 5;
int tab[] = { a , tab[0] + 1 , tab[1] };
它在gcc 4.5和clang 2.9下成功编译并执行,但这种情况是否总是成立?
打印此表将输出5 6 6
。它在全局范围内初始化。
通常对于C和C++都很有趣,但我想在C++中使用它:)
可能是重复的问题:
数组初始化,引用之前的元素是否安全?
我想知道在C/C++标准中这样的初始化是否安全:
int a = 5;
int tab[] = { a , tab[0] + 1 , tab[1] };
它在gcc 4.5和clang 2.9下成功编译并执行,但这种情况是否总是成立?
打印此表将输出5 6 6
。它在全局范围内初始化。
通常对于C和C++都很有趣,但我想在C++中使用它:)
C++03/C++11答案
不,它不会。
在=
的右侧,tab
存在1,但是如果它具有自动存储期,则尚未初始化,因此您对tab[0]
和tab[1]
的使用将使用未初始化的变量。
如果tab
处于命名空间范围(因此具有静态存储期并已进行了零初始化),则这是“安全”的,但是您在那里使用tab[0]
将不会给您5
。
很难为此提供标准参考资料,除了说在8.5“初始值设定项”
中没有明确说明这一点,其他规则填补了其余部分。
1
[n3290: 3.3.2/1]:
名称的声明点位于其完整声明符(第8条)之后,其初始值设定项(如果有)之前[..]
5 6 6
,与我预期的一致。 - qbaint a =5;
int tab[] = { a , tab[0] + 1 , tab[1] };
tab[0]
和tab[1]
是未初始化的,而你使用它们来初始化数组。读取未初始化的变量将引发未定义行为。tab[0]
,你将得到 0 而不是 5? - Christian Rau现在我已经运行了几个测试来解决你的问题。
所有编译都是使用上面的示例代码,并采用以下方案进行的:
$(GCC) -o a.out test.c -Wall -Wextra -pedantic -std=$(STD)
GCC = gcc
,标准 -std=c89; -std=iso9899:1990; -std=iso9899:199409; -std=gnu89
导致出现一个警告:initializer element is not computable at load time
并在运行时显示未定义的行为,这意味着数组的第二个和第三个值是随机垃圾。-std=c99; std=iso9899:1999; -std=gnu99
没有产生此警告,但在运行时也表现出未定义的行为。GCC = g++
,标准 -std=c++98; -std=gnu++98; -std=c++0x
没有产生任何警告,并且代码按照预期工作,导致包含值 {5, 6, 6}
的数组。printf
输出某些内容绝对不是一种未定义行为检测工具。 - Lightness Races in Orbittab[0]
的初始化顺序和用于初始化tab[1]
的表达式tab[0]+1
的求值顺序之间的顺序(它只规定了tab[0]
和tab[1]
的初始化顺序)。是的 - 它很可能会按照您的期望工作。
不是 - (你没有问,但)不要使用它,它没有逻辑性并且是一种不好的做法。
int tab[] = {a, a+1, a+1}
呢?我不明白它的意义。 - Andreas Grapentin