我注意到不允许创建零堆长度的非堆分配数组.
// error: cannot allocate an array of constant length zero
char a[0];
Run Code Online (Sandbox Code Playgroud)
我还注意到它允许创建零长度的堆分配数组.
// this is okay though
char *pa = new char[0];
Run Code Online (Sandbox Code Playgroud)
我猜他们都是标准保证(我手头没有标准副本).如果是这样,为什么他们如此不同?为什么不在堆栈上允许零长度数组(反之亦然)?
Alo*_*ave 16
这在C++标准的以下部分中解决.
3.7.3.1/2:
[32.目的是new()通过调用malloc()或calloc()使操作符可实现,因此规则基本相同.C++与C的不同之处在于要求零请求返回非空指针.
并且,
5.3.4,第7段
当direct-new-declarator中的表达式的值为零时,将调用分配函数以分配不带元素的数组.
C++标准不允许使用大小为0的数组:
8.3.4/1:
"如果存在_constant-expression+(5.19),它应是一个整数常数表达式,其值应大于零."
根据我的理解,这背后的基本原理似乎是C++标准要求每个对象必须具有唯一的地址(这就是为什么即使空类对象的大小为1)也是如此.在非堆零大小的情况下数组,不需要创建任何对象,因此不需要给它任何地址,因此不需要首先允许它.
就c而言,c标准允许零长度数组,通常它们用于通过将零长度数组放置在结构的末尾来实现具有可变大小的结构.如果我的记忆是正确的,它通常被称为C struct Hack.
0长度数组不是很有用.当您计算维度时,它可能会发生,并且不必在代码中专门处理该案例.除此之外new,数组的维度必须是常量,而不是计算值,如果您知道常量为0,为什么要定义它?
至少,这是我听到的理由(来自研究它的人).我并不完全相信:代码中必须使用其值未知的符号常量(来自头文件,甚至是命令行)并不罕见.因此,允许0个元素的数组可能是有意义的.并且过去至少有一个编译器允许它们,尽管我已经忘记了哪个.
C++中的一个常见技巧是在编译时断言中使用这样的数组,如:
char dummyToTestSomeSpecificCondition[ condition ];
Run Code Online (Sandbox Code Playgroud)
如果条件为false,则无法编译,如果不是则将编译.除了那个编译器(如果它仍然存在); 我将使用类似的东西:
char dummyToTestSomeSpecificCondition[ 2 * condition - 1 ];
Run Code Online (Sandbox Code Playgroud)
, 以防万一.