std::uncaught_exception是如何工作的

How does std::uncaught_exception work?

本文关键字:工作 何工作 uncaught exception std      更新时间:2023-10-16

简介

关于CCD_ 1的用法及其合理性,已有文章和文章。

此功能提供的功能可归结为

std::uncaught_exception检测当前是否正在进行堆栈展开。

Q

当搜索它的定义时,我看到的只是对DLL 的调用

_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL uncaught_exception();

如何在程序中实现这种程度的内省这是仅仅用c++就能实现的东西吗?还是编译器/汇编魔法必须发挥作用?

这是编译器的神奇之处,尽管它不需要在汇编中编写。编译器只需要能够访问作为语言运行时环境一部分的一些全局状态。该状态可能对您的程序不可用,但编译器知道如何访问它

有一个C++ABI最初是为安腾平台编写的,但也被其他目标上的一些供应商用作事实上的标准ABI。ABI定义了几个函数和类型,这些函数和类型不是标准C++的一部分,而是由符合安腾ABI的任何C++运行时环境提供的,编译器生成对这些函数的调用,以实现异常处理、动态内存(de(分配、RTTI等功能。

异常处理部分指定每个线程必须有一个类型为__cxa_eh_globals的全局结构,并且实现uncaught_exception()所需的只是查看当前线程结构的uncaughtExceptions成员是否为非零。

显然,上面的详细信息适用于符合该ABI的编译器,但对于具有不同ABI的其他编译器,也会有类似的内容,可能不会公开发布或记录,但编译器本身可以使用。

正如您所看到的,uncaught_exception是库的"语言支持"部分的一部分(第18条,[Language.Support](。也就是说,它是访问核心语言的某些方面所需的库功能(类似于类型标识和初始值设定项列表(。

实现语言支持库通常需要编译器特定的知识,了解一组适当的编译器内部函数,这些函数揭示了核心语言的相关方面。(你不能真正构建一个完全与编译器无关的、"可移植"的C++标准库实现;由于这些语言支持功能,标准库在某种程度上总是与平台绑定在一起。在第18条之外,甚至还有其他类似的情况,例如类型特征。(

异常处理本身内置于核心语言中,并构成编译器ABI的很大一部分;其中一部分是检测异常当前是否处于活动状态。如果在第一个异常处于活动状态时引发第二个异常,则您已经需要这些信息来终止,所以只需要以某种方式公开此状态即可。