c++ - 如果 catch 不执行任何操作,编译器优化会删除 try/catch block 吗?

标签 c++ performance c++11 error-handling c++20

我正在使用具有大量 try catch block 的代码,但大多数情况下 catch block 不执行任何操作。如下面的代码所示,fib 函数抛出 invalid_argument 异常。 main 中的函数调用位于 try block 中,但 catch block 除了捕获异常之外不执行任何操作。

我想知道编译器是否可能在代码优化期间删除这种异常处理?

#include <iostream>
#include <exception>


// Declaration for Wmissing-declarations flag
int fib(int);

int fib(int n)
{
    if (n < 0)
        {
            throw std::invalid_argument("Invalid argument");
        }
    if (n == 0 || n == 1)
        return n;
    
    return fib(n-1) + fib(n-2);
}

int main(int argc, char *argv[])
{
    int _number;
    std::cin >> _number;
    try
    {
        std::cout << fib(_number) << std::endl;
    }
    catch(const std::invalid_argument & e)
    {
        
    }
    return 0;
}

在打开大多数(我所知道的)标志的情况下编译上述代码,如下所示,不会显示任何警告。

g++ -o except exceptions.cxx -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused

最佳答案

I am wondering if the compiler might trim away this kind of exception handling during code optimization, or not?

TL;DR:不,编译器不能不得优化此类异常处理。


mentioned in the comments ,一个 catch阻止与没有 try ... catch 相同 block 。

在您的示例中,尽管 catch 中没有实际执行代码块,当负数传递给 fib 时抛出异常函数仍然被该 block 捕获。此时,catch 从概念上进入该 block ,然后很快退出 - 将控制权(默默地)传递给紧随该空 block 之后的代码。

还会有一些(necessary) stack unwinding ,以及可能的其他“补救”措施,在 catch 时执行 block 被调用;因此,即使是这样一个空的catch block 将实际上仍然捕获相关异常(指定为其参数)。

因此,对于您的代码(按原样),输入测试值 -3将导致程序正常、成功终止。在我的 Windows 控制台(从 Visual Studio 调用)上,我看到以下内容:

-3

C:\SGGCode.exe (process 2888) exited with code 0.
Press any key to close this window . . .

但是,如果我删除 try..catch block ,给出以下 main (保持其他一切不变):

int main(int argc, char* argv[])
{
    int _number;
    std::cin >> _number;
    std::cout << fib(_number) << std::endl; // Removed try...catch
    return 0;
}

然后,当我运行程序并给出相同的输入时,我收到此未捕获的异常错误:

-3

C:\SGGCode.exe (process 2420) exited with code -1073740791.
Press any key to close this window . . .

(请注意, -10737407910xc00004096 ,这是一个 uncaught exception error 。)


为了让事情变得更清晰,请尝试在 return 0; 之前添加如下一行:在你的 main 中:

    std::cout << "See - I'm still here!" << std::endl;

与你的空catch ,将会执行;如果没有它,程序将在到达那里之前崩溃。

关于c++ - 如果 catch 不执行任何操作,编译器优化会删除 try/catch block 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69195593/

相关文章:

c++ - 是否应删除回调传入的 void* 指针

c++ - 在 QTextEdit 中移动光标

mysql - 高效的 DB2 查询分页和显示总页数?

c++ - 接受嵌套的可变类模板作为函数模板的参数

c++ - 使用自动构建系统进行版本控制

c++ - const 有效,但 constexpr 无效

javascript - event.clientX 和 event.clientY 与 event.x 和 event.y

performance - 高效计算 1xM Times MxM Times Mx1, N Times

c++ - 'std::operator 中的 ‘operator<<’ 不匹配

c++ - <函数样式转换> 错误 : Cannot convert from 'initializer list' to 'std::thread'