【发布时间】:2017-04-03 16:07:58
【问题描述】:
在以下程序中:
#include <iostream>
struct I {
int i;
I(){i=2;}
I(int _i){i=_i;}
};
int a[3] = {a[2] = 1};
int aa[3][3] = {aa[2][2] = 1};
I A[3] = {A[2].i = 1};
I AA[3][3] = {AA[2][2].i = 1};
int main(int argc, char **argv) {
for (int b : a) std::cout << b << ' ';
std::cout << '\n';
for (auto &bb : aa) for (auto &b : bb) std::cout << b << ' ';
std::cout << '\n';
for (auto &B : A) std::cout << B.i << ' ';
std::cout << '\n';
for (auto &BB : AA) for (auto &B : BB) std::cout << B.i << ' ';
std::cout << '\n';
return 0;
}
输出是
1 0 0
1 0 0 0 0 0 0 0 1
1 2 2
1 2 2 2 2 2 2 2 2
来自 http://ideone.com/1ueWdK 和 clang3.7
但结果是:
0 0 1
1 0 0 0 0 0 0 0 1
1 2 2
1 2 2 2 2 2 2 2 2
在 http://rextester.com/l/cpp_online_compiler_clang 上也使用 clang 3.7。
在我自己的 ubuntu 上,gcc 6.2 在构造 int aa[3][3] = {aa[2][2] = 1} 上出现内部编译器错误。
我假设这是未定义的行为,但在标准中找不到明确的声明。
问题是:
标准中定义的初始化列表(例如a[2] = 1)中赋值的副作用和数组实际元素的初始化(例如a[2])的评估顺序?
明确声明为已定义或未定义?还是因为没有明确定义而变得未定义?
或者由于评估顺序之外的其他原因,构造是否具有已定义或未定义的行为?
【问题讨论】:
-
我的眼睛在流血......如果这不是一个赞成票,我不知道会是什么......
-
Doesn't compile。如果您的代码如此混乱以至于编译器的解析器崩溃,也会导致内部编译器错误。
-
在 gcc 4.9 中编译并且 clang ... gcc 5+ 有一个错误
标签: c++ initialization language-lawyer aggregate-initialization