std::uncaught_exception
的使用和理性有posts和articles。
此功能提供的Functionality归结为
std :: uncaught_exception检测当前是否正在进行堆栈展开。
在搜索其定义时,我看到的是对DLL的调用
_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL uncaught_exception();
如何实现程序中的这种内省程度?仅仅通过c ++或编译器/程序集魔术可以实现这一点吗?
答案 0 :(得分:5)
这是编译魔术,虽然它不需要在汇编中编写。编译器必须能够访问属于语言运行时环境的某些全局状态。该程序可能无法使用该状态,但编译器知道如何访问它。
最初为Itanium平台编写了一个C++ ABI,但其他目标上的几个供应商也使用它作为事实上的标准ABI。 ABI定义了几个不属于标准C ++的函数和类型,但是由符合Itanium ABI的任何C ++运行时环境提供,并且编译器生成对这些函数的调用,以实现异常处理,动态等功能。内存(de)分配,RTTI等。
exception handling部分指定每个线程必须有__cxa_eh_globals
类型的全局结构,实现uncaught_exception()
所需的全部内容是查看uncaughtExceptions
成员当前线程的结构是非零的。
显然上面的细节适用于符合ABI的编译器,但对于具有不同ABI的其他编译器,会有类似的东西,可能没有公开发布或记录,但编译器本身可以使用。
答案 1 :(得分:3)
正如您所看到的,uncaught_exception
是语言支持的一部分"图书馆的一部分(第18条,[language.support])。也就是说,它是访问核心语言某些方面所需的库功能(类似于类型识别和初始化列表等)。
实现语言支持库通常需要编译器特定的一组适当的编译器内在函数知识,这些知识可以揭示核心语言的相关方面。 (你无法构建一个完全与编译器无关的,可移植的" C ++标准库实现;由于这些语言支持功能,标准库总是在某种程度上与平台绑定。甚至还有其他这样的情况第18条,例如类型特征。)
异常处理本身内置于核心语言中,构成了编译器ABI的很大一部分;部分原因是检测异常当前是否处于活动状态。如果在第一个异常处于活动状态时抛出第二个异常,则您已经需要此信息才能终止,所以这只是以某种方式暴露此状态的问题。