在C ++中,与C不同,空数组T name[]
是非法的,
声明的类型是" T"的未知界限数组,这是一种不完整的类型。
然而,
时是合法的在具有聚合初始值设定项的声明中使用
与T name[] = {val1, val2, ...}
类似,其中数组分配了初始化列表中的元素数。
聚合初始值设定项为空时的预期行为是什么? T name[] = {}
我测试了g ++(版本4.8.4)和clang(版本3.4),它们都没有给出任何错误或警告,并且似乎分配了1个元素。这是定义的行为吗?文档?
int a[] = {};
int b[] = {};
结果:
a[0] -> 0x7ffc3de28dd8
a[1] -> 0x7ffc3de28ddc
b[0] -> 0x7ffc3de28ddc
b[1] -> 0x7ffc3de28de0
答案 0 :(得分:2)
根据C ++标准1.8.6(C ++ 14):
如果不是位字段,则两个对象可能具有相同的地址 是另一个的子对象,或者如果至少有一个是基类 零大小的子对象,它们是不同类型的;除此以外, 他们应该有不同的地址.4
编译器必须至少分配一个数组元素才能满足上述要求。
答案 1 :(得分:2)
从工作草案[8.5.1/5](聚合):
空的初始化列表{}不能用作未知边界数组的initializer子句。
语法提供了空的初始化列表,但是C ++没有零长度数组。
听起来像是UB。
另请注意,这会按预期编译:
template<int N>
void f(int(&)[N]) { }
int main() {
int v[] = {42};
f(v);
}
但如果你使用它,它就不再起作用了:
int v[] = {};
使用GCC进行测试。