使用聚合初始化程序声明空C ++数组

时间:2016-06-28 17:47:07

标签: c++ arrays

在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

2 个答案:

答案 0 :(得分:2)

根据C ++标准1.8.6(C ++ 14):

  

如果不是位字段,则两个对象可能具有相同的地址   是另一个的子对象,或者如果至少有一个是基类   零大小的子对象,它们是不同类型的;除此以外,   他们应该有不同的地址.4

编译器必须至少分配一个数组元素才能满足上述要求。

答案 1 :(得分:2)

从工作草案[8.5.1/5]聚合):

  

空的初始化列表{}不能用作未知边界数组的initializer子句。

另见[footnote/105]

  

语法提供了空的初始化列表,但是C ++没有零长度数组。

听起来像是UB。

另请注意,这会按预期编译:

template<int N>
void f(int(&)[N]) { }

int main() {
    int v[] = {42};
    f(v);
}

但如果你使用它,它就不再起作用了:

int v[] = {};

使用GCC进行测试。