声明带有聚合初始化器的空c++数组

Declaring empty C++ array with aggregate initializer

本文关键字:c++ 数组 初始化 声明      更新时间:2023-10-16

在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

来自工作草案,[8.5.1/5]( aggregate ):

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

参见[footnote/105]:

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

听起来像UB。


还请注意,这将按预期编译:

template<int N>
void f(int(&)[N]) { }
int main() {
    int v[] = {42};
    f(v);
}

但是如果你使用:

它就不起作用了
int v[] = {};

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

两个不是位域的对象可以有相同的地址是另一个的子对象,还是至少有一个是基类零大小的子对象,它们是不同类型的;否则,它们应当有不同的地址。4

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