std::current_exception 是否应该从类析构函数中的 catch 块返回非空值
Should std::current_exception return non-null from catch block in a class's destructor
我和我的同事认为我们在Visual C++2012和2013中发现了一个错误,但我们不确定。以下代码中对std::current_exception的调用是否应该返回非null exception_ptr?在我们尝试过的大多数其他编译器上似乎都是这样:
#include <exception>
#include <stdexcept>
#include <iostream>
class A
{
public:
~A()
{
try
{
throw std::runtime_error("oh no");
}
catch (std::exception &)
{
std::clog << (bool)std::current_exception() << std::endl;
}
}
};
void foo ()
{
A aa;
throw std::runtime_error("oh no");
}
int main(int argc, char **)
{
try
{
foo();
}
catch(...)
{
}
return 0;
}
当在Visual C++下运行时,我们得到"0"(false,这意味着返回的exception_ptr为null)。其他编译器,如g++,打印"1"。
cppreference这样描述std::current_exception
:
如果在异常处理期间调用(通常在catch子句中),则捕获当前异常对象并创建一个std::exception_ptr,该std::xception_ptr保存对该异常对象的副本或引用(如果生成副本,则由实现定义)。
如果此函数的实现需要调用new,而调用失败,则返回的指针将包含对std::bad_alloc 实例的引用
如果此函数的实现需要复制捕获的异常对象,并且其复制构造函数抛出异常,则返回的指针将包含对抛出的异常的引用。如果抛出的异常对象的复制构造函数也抛出,则返回的指针可能包含对std::bad_exception实例的引用,以打破无休止的循环。
如果在没有处理异常的情况下调用该函数,则返回一个空的std::exception_ptr。
引发异常展开堆栈,该堆栈应在aa
实例上调用A
类的析构函数,其中有一个捕获异常的简单try/throw/catch
代码块。
当然,它没有标准那么权威,但在我看来,g++/crang是正确的,而视觉则不是(相反,这种情况发生的频率较低:p)
正如James McNellis所证实的,这绝对是一个bug。今天我很高兴发现了它。
在您的情况下,解决方法是在处理程序中调用make_exception_ptr
而不是current_exception
:
~A()
{
try
{
throw std::runtime_error("oh no");
}
catch (std::exception & e)
{
std::clog << (bool)std::make_exception_ptr(e) << std::endl;
}
}
但我认为我们在catch(...)
条款方面运气不佳,确实需要进行修复。
第1版:我很久以前在"connect"中报告过这个错误。它现在可以在Developper社区上找到。
第2版:该错误已在VS2019 16.3中修复。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- std::current_exception 是否应该从类析构函数中的 catch 块返回非空值
- Try/Catch VS在C++中返回错误代码
- try-catch对char**返回值有影响