#include <stdlib.h>
void *operator new[](size_t size, int n){
if( size != 0 && n != 0 )
return calloc(n, size);
return calloc(1, 1);
}
int main(){
int * p1;
const int i = 0;
// p1 = new (20) int[i] ; // Case 1 (OK)
p1 = new (20) (int[i]); // Case 2 (Warning)
if( p1 == 0 )
return 1;
return 0;
}
这段代码(https://godbolt.org/g/hjo7Xn)在Clang 6.0.0下编译成功,但是在GCC 7.3下会发出警告,表示C++中禁止使用零长度数组。如果移除括号(情况1),则警告消失。
与静态分配的零长度数组不同(C++03:8.3.4/1),动态分配的零长度数组是允许的(C++03:5.3.4/6)。然而,在C++标准中,只有遵循new-expression的两种可能语法路径之一时,即使用new-type-id而不使用括号的路径(情况1),后者才被明确允许。
C++标准是否允许使用带有括号的type-id(情况2)来跟随零长度数组的new-expression第二个语法路径?
唯一相关的引用是C++03:5.3.4/5:
当分配的对象是数组(即使用direct-new-declarator语法或new-type-id或type-id表示数组类型时),new-expression将产生指向数组的初始元素(如果有的话)的指针。
(如果有)
这个措辞允许一个没有元素的数组,但是它似乎不清楚它是指两种情况还是只指没有括号的new-type-id(第一种情况)。
提前致谢。
注:
- ISO/IEC 14882:2003第8.3.4节第1段:
如果存在constant-expression(5.19),则它应该是一个整数常量表达式,其值应大于零。 - ISO/IEC 14882:2003第5.3.4节第6段: direct-new-declarator中的expression应具有整数或枚举类型(3.9.1)并具有非负值。
- ISO/IEC 14882:2003第5.3.4节第7段:
当direct-new-declarator中的expression的值为零时,调用分配函数以分配一个没有元素的数组。 - ISO/IEC 14882:2003第5.3.4节第1段:
new-expression:
::
opt
new new-placementopt
new-type-id new-initializeropt
::opt
new new-placementopt
( type-id ) new-initializeropt
- 尽管上述引用来自C++03标准,但据我所知,这个问题在更新版本的C++标准(C++11、C++14和C++17)中仍不清楚。
- 有趣的Herb Sutter关于零长度数组的post。
- 示例中的代码是从SolidSands' SuperTest套件中稍微修改的测试。
operator new[]
是什么意思?这和任何事情有关系吗? - Cheers and hth. - Alf