【发布时间】:2018-10-10 20:51:32
【问题描述】:
#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 的语法路径em> 且不带括号(案例 1)。
C++ 标准是否允许使用 new-expression 和第二个语法路径后的零长度数组,即 type-id em> 和括号(案例 2)?
唯一相关的引用是 C++03:5.3.4/5:
当分配的对象为数组时(即使用direct-new-declarator语法或new-type-id或type- id 表示一个数组类型),new-expression 产生一个指向数组初始元素(如果有的话)的指针。
措辞(if any) 将允许一个没有元素的数组,但是,似乎不清楚它是指这两种情况还是仅指具有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 中的表达式 应具有非负值的整数或枚举类型 (3.9.1)。
- ISO/IEC 14882:2003,第 5.3.4 节,第 7 段:
当direct-new-declarator中表达式的值为零时,调用分配函数分配一个没有元素的数组。
- ISO/IEC 14882:2003,第 5.3.4 节,第 1 段:
新表达式:
::
optnew new-placementoptnew-type-id new-initializeropt::
optnew new-placementopt( type-id ) new-initializeropt - 虽然以上引用来自 C++03 标准,但据我所知,这个问题在新版本的 C++ 标准(C++11、C++14 和 C++17)中仍然不清楚.
- 有趣的 Herb Sutter 的 post 关于零长度数组。
- 示例中的代码是来自SolidSands' SuperTest 套件的稍微修改的测试。
【问题讨论】:
-
只是好奇:如果您希望符合 C++11 标准,是否有理由引用 C++03 标准?因为网上有各种草稿,可能更容易引用/链接。
-
自定义越野车
operator new[]是怎么回事?这跟什么有什么关系? -
没有来自 gcc 8 的警告。
-
@Rakete1111我对从 C++03 开始的合规性感兴趣。但你是对的,最好只链接到标准而不是直接引用。如果我发现每个部分(不是 PDF)C++03 标准的在线链接,我会更新帖子。
-
@Cheersandhth.-Alf 我认为问题是一样的,我离开它是因为我不想修改那么多原始测试(我已经在其他部分减少了它)。为什么它有问题?
标签: c++ arrays c++11 new-operator dynamic-memory-allocation