隐式异常处理

Implicit exception handling

我对 C++ 编译器如何实现异常处理有了一个基本的了解,这要归功于 Vishal Kochhar 的优秀article。基本上,只要 try/catch 构造出现在函数中,编译器就会生成 prologue/epilogue 代码,如下所示:

push -1
push offset new_handler
mov eax, fs:[0]
push eax ; old handler saved on the stack
mov fs[0], esp
...
mov ecx, [ebp-0Ch] ; recover old handler
mov fs[0], ecx

请问,为什么编译器会把这样的东西插入到看似与异常处理无关的函数中?根据源代码,我敢肯定,他们体内没有 try/catch 块。

这些函数 "which seemingly have nothing to do with exception handling" 可能 运行ning finalisers/destructors 在它们的局部变量上。对象的终结器必须在其作用域结束后立即为 运行,无论是正常的 return 还是未捕获的异常,因此函数必须在序言中安装异常处理程序以确保在任何情况下都调用终结器.

D 中触发此行为的简单示例:

struct Foo {
    ~this() {
        ;
    };
};

int main() {
    Foo x;
    return 0;
};

也许聪明的编译器能够在 nothrow 函数中省略 prologue/epilogue 例如:

struct Foo {
    ~this() nothrow {
        ;
    };
};

int main() nothrow {
    Foo x;
    return 0;
};

但似乎不是这种语言。