std::async 如何"store"任意异常?
How does std::async "store" an arbitrary exception?
我无法理解std::async
如何存储任何异常,而不仅仅是从std::exception
派生的异常。我玩了下面的代码
#include <iostream>
#include <future>
#include <chrono>
void f()
{
std::cout << "ttIn f() we throw an exception" << std::endl;
throw 1; // throw an int
}
int main()
{
std::future<void> fut = std::async(std::launch::async, f);
std::cout << "Main thread sleeping 1s..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1)); // sleep one second
std::cout << "Main thread waking up" << std::endl;
try
{
fut.get();
}
catch(...)
{
std::cout << "We caught an exception!" << std::endl;
throw; // rethrow
}
}
我异步启动f()
,然后在f
中抛出一个int
。神奇的是,这个int
被std::async
返回的future捕获并存储。我知道catch(...)
可以在std::async
中存储异常,但后者如何在不知道异常类型的情况下存储它?异常不是从某个基类派生的(在这种情况下,可能可以通过某个Base::clone
"克隆"它),但可以是任何异常。我们能神奇地"推导"出异常类型吗?
总之,我的问题是:
在不知道异常类型的情况下,我们如何将任意异常存储在对象中,然后在以后的某个时间重新抛出它?
std::async
可以在std::thread
和std::packaged_task
之上实现。
CCD_ 14可以(部分)在CCD_ 15和相关函数(线程退出准备函数除外)之上实现。
CCD_ 16及相关函数不能用C++编写。
我不确定这是否能准确回答您的问题,但这个例子可能会有所帮助。
我编译了以下内容:
int main()
{
throw 1;
}
使用命令
g++ -fdump-tree-gimple -std=c++11 main.cpp -o main
万向节(gcc的中间输出)是:
int main() ()
{
void * D.1970;
int D.1974;
D.1970 = __cxa_allocate_exception (4);
try
{
MEM[(int *)D.1970] = 1;
}
catch
{
__cxa_free_exception (D.1970);
}
__cxa_throw (D.1970, &_ZTIi, 0B);
D.1974 = 0;
return D.1974;
}
所以它用一个表示类型的符号的地址来调用__cxa_throw
。在这种情况下,类型是_ZTIi
,它是整数的损坏类型。
编译时不可用的类型
类型符号只需要在运行时可用。在一个试图隐藏尽可能多的符号的动态库中,它需要确保任何没有在内部捕获和处理的异常都是可用的。有关更多信息,请参阅https://gcc.gnu.org/wiki/Visibility特别是Problems with C++ exceptions (please read!)
。
看看这在使用不同命名方案的编译器编译的动态库之间是如何工作的,会很有趣。
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 尝试使用智能指针时引发异常
- 从函数返回任意简单类型的数据
- 函数如何通知用户它基于函数原型抛出异常?
- std::async 如何"store"任意异常?