uni*_*n83 34 c++ exception-handling g++ exit
这个C++程序是一个CGI脚本,我不想处理异常.我宁愿获得边际性能提升,让操作系统(Linux)在进程终止后处理清理.
我正在使用标准C++库,并希望die在Perl中使用任何函数:每当它抛出异常时.没有展开,或在我的过程中运行任何进一步的代码.
-fno-exceptions如何工作?如果我的代码中根本没有捕获,并且基本上假装不存在异常.但我确实使用std :: c ++库,可以 throw()?
bdo*_*lan 66
选项#1:简单地从不捕获异常.
当他们没有被抛出或被抓住时,例外没有太大的开销; 如果你正在投掷并且没有准备好赶上,那么你无论如何都要死,所以那时的表现影响是微不足道的.另请注意,如果未处理异常,则不会执行堆栈展开; 程序将直接终止而不执行堆栈展开.
值得注意的是,在G ++中,异常几乎没有实际抛出的开销.G ++生成足够的额外信息以通过堆栈追溯程序的执行,以及一些额外的代码来调用析构函数等 - 但是在实际抛出异常之前,不会使用这些额外的代码或数据.因此,您不应该看到启用了异常但未使用的代码与禁用异常的代码(通过任何机制)之间的性能差异.
选项#2:通过-fno-exceptions.
这个标志指示G ++ 做两件事:
abort()电话取代-fno-exceptions代码展开,它将在该点中止,因为没有展开数据.这将有效地将所有异常转换为abort()s,如您所愿.但请注意,您不会被允许throw- 代码中的任何实际throws或catchs都将导致编译时错误.
选项#3 :(不可移植,不推荐!)挂钩__cxa_allocate_exception.
使用(其中包括)__cxa_allocate_exception和__cxa_throw内部库函数来实现C++异常.您可以实现将这些函数挂接到abort()的LD_PRELOAD库:
void __cxa_allocate_exception() { abort(); }
void __cxa_throw() { abort(); }
Run Code Online (Sandbox Code Playgroud)
警告:这是一个可怕的黑客攻击.它应该适用于x86和x86-64,但我强烈建议不要这样做.值得注意的是,它实际上不会提高性能或节省代码空间-fno-exceptions.但是,它将允许throw 语法,同时将throws转换为abort()s.
GMa*_*ckG 19
-fno-exceptions将所有标准库throw转换为调用std::abort().它处理你不能直接修改的部分,其余的是在代码中根本不使用它们.
当然,我真的怀疑你这样做的理由.当你实际投掷时,你只会"失去"表现,并且你会丢掉一个重要且有用的语言.
Fre*_*pin 11
万一有人偶然发现这个问题,我想纠正@GManNickG和(/sf/answers/507462231/)和@bdonlan(/sf/answers/507460971/))在答案中说.不幸的是,关于"-fno-exception"删除所有异常处理代码并将所有抛出中止的部分都是错误的.好吧 - 部分错了.当您使用此标志编译有问题的库(libstdc ++ v3)时,这是正确的,但如果您在使用此标志编译的自己的代码中使用此库(作为.a或.so或.dll或其他),则为true .在后一种情况下,您的代码中的异常处理代码是被禁止的,但是库内的所有异常处理调用仍然存在(因为库是在没有此标志的情况下编译的,启用了异常),所以如果您使用new那么您的可执行文件将具有异常处理代码 - 唯一的区别是你不能对这些异常做任何事情catch()(在你的代码中被禁止),所以所有抛出都会有效地结束abort(),但只是因为没有人抓住它们.