禁用C ++异常,我如何使任何std :: throw()立即终止? [英] Disabling C++ exceptions, how can I make any std:: throw() immediately terminate?

查看:243
本文介绍了禁用C ++异常,我如何使任何std :: throw()立即终止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个C ++程序是一个CGI脚本,我不想处理异常。我宁愿获得一个边际的性能提升,让操作系统(Linux)在进程死机之后处理清理。



我正在使用标准C ++库,并希望任何功能到 die 像在Perl中一样:每当它引发异常。在我的进程中不需要展开,或者运行任何进一步的代码 。



-fno-exceptions如何工作?如果我的代码中没有任何东西,并且基本上假装像例外那样不存在。但是我 do 使用std :: c ++库,可以 throw()?

解决方案

选项#1:永远不会捕获异常。



异常在没有被抛出或被捕获时没有太多的开销;如果你扔了,没有准备好赶上,那么你还在做死,所以在这一点上的表现影响是微不足道的。还要注意,如果未处理异常,则不会执行堆栈展开;程序将简单地终止,而不执行堆栈展开。



重要的是要注意,在G ++中,异常几乎没有开销,实际上并没有被抛出。 G ++产生足以追溯程序通过堆栈执行的额外信息,还有一些额外的代码来调用析构函数等,但是在实际抛出异常之前,这些额外的代码或数据都不会被使用。因此,您不应该看到代码与启用异常但未使用的代码之间的性能差异,以及禁用异常的代码(通过任何机制)。



选项#2:通过 -fno-exceptions



此标志指示G ++为做两件事情:


  1. STL库中的所有异常处理都将被删除; throws被替换为 abort()调用

  2. 堆栈放卷数据和代码被删除。这节省了一些代码空间,并且可能使编译器的注册分配容易一些(但我怀疑它会有很大的性能影响)。然而,值得注意的是,如果抛出异常,并且库尝试通过 -fno-exceptions 代码解开,那么它将在此时中止,因为没有展开数据。

这将有效地将所有异常转换为 abort()像你想要的请注意,您不会被允许 throw - 任何实际的 throw s或在代码中捕获将导致编译时错误。



选项3:(不可推荐,不推荐!)Hook __cxa_allocate_exception。



使用(等)__cxa_allocate_exception和__cxa_throw内部库函数实现C ++异常。您可以实现一个将这些函数挂接到abort()的LD_PRELOAD库:

  void __cxa_allocate_exception(){abort(); } 
void __cxa_throw(){abort(); }

警告:这是一个可怕的黑客。它应该在x86和x86-64上工作,但我强烈建议不要这样做。值得注意的是,它不会实际上提高性能或节省代码空间,因为 -fno-exceptions 可能。然而,它将允许 throw 语法,同时将 throw s转换为 abort() s。


This C++ program is a CGI script, I have no desire to deal with exceptions. I'd rather get a marginal performance boost and let the OS (Linux) handle cleanup after the process dies.

I am using the Standard C++ Library, and want any function to die like in Perl: Whenever it throws an exception. Without unwinding, or running any further code in my process.

How does -fno-exceptions work? If I have no catch at all in my code, and basically pretend like exceptions do no exist. but I do use std:: c++ library which can throw()?

解决方案

Option #1: Simply never catch exceptions.

Exceptions don't have much overhead when they're not thrown or caught; if you're throwing and not prepared to catch, well, you're doing to die anyway, so the performance impact at that point is trivial. Note also that stack unwinding will not be performed if an exception is not handled; the program will simply terminate without performing stack unwinding.

It's important to note that, in G++, exceptions have almost no overhead when not actually thrown. G++ generates extra information sufficient to trace back the execution of the program through the stack, and some extra code to invoke destructors, etc - however none of this extra code or data is ever used until an exception is actually thrown. So you should not see a performance difference between code with exceptions enabled but not used and code with exceptions disabled (through whatever mechanism).

Option #2: Pass -fno-exceptions.

This flag instructs G++ to do two things:

  1. All exception handling in STL libraries are removed; throws are replaced with abort() calls
  2. Stack unwind data and code is removed. This saves some code space, and may make register allocation marginally easier for the compiler (but I doubt it'll have much performance impact). Notably, however, if an exception is thrown, and the library tries to unwind through -fno-exceptions code, it will abort at that point, as there is no unwind data.

This will, effectively, turn all exceptions into abort()s, as you would like. Note, however, that you will not be allowed to throw - any actual throws or catchs in your code will result in a compile-time error.

Option #3: (Nonportable and not recommended!) Hook __cxa_allocate_exception.

C++ exceptions are implemented using (among others) the __cxa_allocate_exception and __cxa_throw internal library functions. You can implement a LD_PRELOAD library that hooks these functions to abort():

void __cxa_allocate_exception() { abort(); }
void __cxa_throw() { abort(); }

WARNING: This is a horrible hack. It should work on x86 and x86-64, but I strongly recommend against this. Notably, it won't actually improve performance or save code space, as -fno-exceptions might. However, it will allow the throw syntax, while turning throws into abort()s.

这篇关于禁用C ++异常,我如何使任何std :: throw()立即终止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆