如果 catch 什么都不做,编译器优化会删除 try/catch 块吗?
Would compiler optimization remove try/catch block if catch does nothing?
我使用的代码有很多 try
catch
块,但大多数情况下 catch
块什么都不做。在下面的代码中,fib
函数抛出 invalid_argument
异常。 main
中的函数调用在 try
块中,但 catch
块除了捕获异常外什么都不做。
我想知道编译器是否可能 trim 在代码优化期间取消这种异常处理?
#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: 不,编译器不能并且不能优化掉这样的异常处理。
作为,一个空 catch
块是不是 与没有 try ... catch
块相同。
在你的例子中,虽然 catch
块中没有实际 执行 的代码,但将负数传递给 [=17= 时抛出的异常] 函数 仍然被那个块 捕获。那时,catch
块是 在概念上 进入,然后很快退出 - 将控制权(静默地)传递给紧随该空块之后的代码。
还会有一些 ,可能还有其他 'remedial' 操作,在 catch
块被调用时执行;因此,即使是这样一个空的 catch
块也会 实际上捕获 相关异常(指定为它的参数)。
因此,对于您的代码(按原样),输入 -3
的测试值将导致程序正常、成功终止。在我的 Windows 控制台上(从 Visual Studio 调用),我看到了这个:
-3
C:\SGGCode.exe (process 2888) exited with code 0.
Press any key to close this window . . .
但是,如果我删除 try..catch
块,则给出以下 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 . . .
(注意 -1073740791
是 0xc00004096
,这是一个 uncaught exception error。)
为了让事情更清楚 位 ,请尝试在 main
中的 return 0;
行之前添加如下一行:
std::cout << "See - I'm still here!" << std::endl;
用你的空catch
,那将执行;没有它,程序会在到达那里之前崩溃。
我使用的代码有很多 try
catch
块,但大多数情况下 catch
块什么都不做。在下面的代码中,fib
函数抛出 invalid_argument
异常。 main
中的函数调用在 try
块中,但 catch
块除了捕获异常外什么都不做。
我想知道编译器是否可能 trim 在代码优化期间取消这种异常处理?
#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: 不,编译器不能并且不能优化掉这样的异常处理。
作为catch
块是不是 与没有 try ... catch
块相同。
在你的例子中,虽然 catch
块中没有实际 执行 的代码,但将负数传递给 [=17= 时抛出的异常] 函数 仍然被那个块 捕获。那时,catch
块是 在概念上 进入,然后很快退出 - 将控制权(静默地)传递给紧随该空块之后的代码。
还会有一些 catch
块被调用时执行;因此,即使是这样一个空的 catch
块也会 实际上捕获 相关异常(指定为它的参数)。
因此,对于您的代码(按原样),输入 -3
的测试值将导致程序正常、成功终止。在我的 Windows 控制台上(从 Visual Studio 调用),我看到了这个:
-3
C:\SGGCode.exe (process 2888) exited with code 0.
Press any key to close this window . . .
但是,如果我删除 try..catch
块,则给出以下 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 . . .
(注意 -1073740791
是 0xc00004096
,这是一个 uncaught exception error。)
为了让事情更清楚 位 ,请尝试在 main
中的 return 0;
行之前添加如下一行:
std::cout << "See - I'm still here!" << std::endl;
用你的空catch
,那将执行;没有它,程序会在到达那里之前崩溃。