【问题标题】:How does std::uncaught_exception work?std::uncaught_exception 是如何工作的?
【发布时间】:2014-08-02 19:22:24
【问题描述】:

简介

std::uncaught_exception的用法和合理性有postsarticles

这个函数提供的Functionality归结为

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

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

_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL uncaught_exception();

如何在程序中实现这种级别的自省?这是否可以仅通过 c++ 实现,或者必须发挥编译器/汇编的魔力?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

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

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

    exception handling 部分指定每个线程必须有一个__cxa_eh_globals 类型的全局结构,实现uncaught_exception() 所需要做的就是查看当前线程结构的uncaughtExceptions 成员是否为非零。

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

    【讨论】:

      【解决方案2】:

      如您所见,uncaught_exception 是库的“语言支持”部分的一部分(第 18 条,[language.support])。也就是说,它是访问核心语言某些方面所需的库功能(类似于类型识别和初始化列表等)。

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

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

      【讨论】:

        猜你喜欢
        • 2016-11-15
        • 1970-01-01
        • 2013-06-15
        • 2012-12-15
        • 2017-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多