c++ 为什么编译器不能优化try-catch块中的单个throw语句?

sg24os4d  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(90)

我只是在Compiler Explorer上玩了一些C++代码,在编译一个简单的try/catch块时注意到一些意想不到的行为。下面的两个片段都是用gcc使用优化标志-O3live example)编译的。
在第一个程序中,整个try/catch块被删除,因为在行为上没有明显的差异,导致与return 0;相同的程序集。这正是我期望编译器产生的结果。

int main() {
    try {
        int x{ 10 };
    }
    catch (...) {
    }

    return 0;
}

个字符
在第二个代码片段中,我throw一个异常,而不是仅仅初始化一个int。在抛出该异常之后,我将继续在catch-all处理程序中,该处理程序为空。之后只有return 0;语句。这意味着该程序的可观察行为与第一个相同。然而,程序集显示,整个try/catch仍在继续。

int main() {
    try {
        throw 10;
    }
    catch (...) {
    }

    return 0;
}
main:
        push    rcx
        mov     edi, 4
        call    __cxa_allocate_exception
        xor     edx, edx
        mov     esi, OFFSET FLAT:_ZTIi
        mov     DWORD PTR [rax], 10
        mov     rdi, rax
        call    __cxa_throw
        mov     rdi, rax
        call    __cxa_begin_catch
        call    __cxa_end_catch
        xor     eax, eax
        pop     rdx
        ret

的字符串
现在我想知道为什么编译器不能识别整个try/catch块是“死代码”(或者不是?),或者如果它能识别它,为什么它没有优化它。

8fsztsew

8fsztsew1#

第一个例子相当于:

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

字符串
由于try块中的语句是安全的,编译器检测到catch块永远不会到达,并且它可以通过删除try catch块来进行优化。
在第二个代码段中,你抛出了一个异常,这样try catch块就不是死代码,因为即使它是空的,控件也会进入catch块。

为什么没有优化掉?

虽然catch块中没有执行任何代码,但抛出的异常将继续飞行,除非被catch块显式地处理。因此,执行将进入catch块,然后退出它并将控制(静默)传递给空块后面的代码。

相关问题