考虑以下示例:
template<int N>
struct foo {
constexpr foo() : a() {}
int a[N];
};
int main() {
foo< (foo<1>{}).a[0] > f;
}
尝试编译时,clang会将foo<0>
推断为f
的类型,而g++
会因内部编译器错误而崩溃。
但是,a
- foo<1>
的成员是否保证为零,或者这是未定义/未指定的行为?
答案 0 :(得分:6)
成员初始化程序a()
值初始化foo::a
(通过[class.base.init] / 7,这会导致[dcl.init] / 11)。 [dcl.init] / 8指定数组的值初始化值初始化数组的每个元素。对于int
s(和其他基本类型),这会导致零初始化。
这与constexpr
无关。内部编译器错误通常是一个错误;它也可能意味着你超出了一些实现定义的限制 - 这似乎不是这里的情况。
如注释中的Piotr S.注释,如果我们假设foo< (foo<1>{}).a[0] >
,则表达式foo<1>{}).a[0] == 0
会导致声明零大小的数组。这些在C ++中是不合法的;所以有人可能会说g ++的行为是合规的。