new(std::nothrow) int[n] 抛出异常
Posted
技术标签:
【中文标题】new(std::nothrow) int[n] 抛出异常【英文标题】:new(std::nothrow) int[n] throws an exception 【发布时间】:2019-12-19 17:51:45 【问题描述】:#include <iostream>
#include <new>
int main()
int n = -1;
try
int *p = new(std::nothrow) int[n];
if(!p)
std::cout << "new expression returned nullptr\n";
catch(const std::bad_array_new_length& e)
std::cout << "new expression threw " << e.what() << std::endl;
为什么这段代码会抛出异常?它打印new expression threw std::bad_array_new_length
。
根据标准,在这种情况下,新表达式应返回 nullptr。
如果 noptr-new-declarator 中的表达式存在,它是 隐式转换为 std::size_t。如果出现以下情况,则表达式错误:
——表达式是非类类型,它在转换为之前的值 std::size_t 小于零;
[...]
如果表达式错误 转换为 std::size_t 后:
——如果表达式是核心 常量表达式,程序格式错误;
——否则,一个 不调用分配函数;而是
——如果分配 本来会被调用的函数有一个非抛出异常 规范(14.5),新表达式的值为空 所需结果类型的指针值;
——否则, new-expression 通过抛出一个类型的异常来终止 将匹配 std::bad_array_new_length 类型的处理程序 (14.4) (17.6.3.2)。
使用 gcc 9.2 编译
【问题讨论】:
归档gcc bug 93016。 嗯。顺便说一句,“转换为 std::size_t 之后”看起来是错误的。也许是标准委员会的编辑错误? 这是Core issue 1992。 @T.C.它应该抛出还是一个错误?我从文本中没有理解这一点。 @Lassie 核心问题表明抛出异常曾经是标准中的一个错误。 【参考方案1】:我怀疑这是 libstdc++ 中的一个错误;使用 clang 和 libc++ 运行此代码会打印“新表达式返回 nullptr”
【讨论】:
libstdc++ 的错误?几乎没有,这在编译器中。 @Deduplicator - 我不这么认为。看看the libc++ implementation 这表明他们的 nothrow op-new 函数正确地吞下了所有异常。但是到那时,人们再也无法检查是否超出了实施限制或负输入,那列火车早就离开了车站。因此,这里无关紧要。 是的,这不是图书馆的问题。以上是关于new(std::nothrow) int[n] 抛出异常的主要内容,如果未能解决你的问题,请参考以下文章