gpt4 book ai didi

c++ - 禁用 C++ 异常,如何使任何 std::throw() 立即终止?

转载 作者:IT老高 更新时间:2023-10-28 12:36:31 30 4
gpt4 key购买 nike

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

我正在使用标准 C++ 库,并且希望任何函数die 就像在 Perl 中一样:只要它抛出异常。 不展开,或运行任何进一步的代码在我的过程中。

-fno-exceptions 是如何工作的?如果我的代码中根本没有捕获,并且基本上假装不存在异常。但我确实使用可以 throw()的std::c++库?

最佳答案

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

异常在没有被抛出或捕获时不会产生太多开销;如果您正在 throw 并且不准备接住,那么无论如何您都会死,因此此时对性能的影响是微不足道的。另请注意,如果未处理异常,则不会执行堆栈展开;程序将直接终止而不执行堆栈展开。

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

选项 #2:传递 -fno-exceptions

这个标志指示 G++ do two things :

  1. 删除了 STL 库中的所有异常处理; throws 被替换为 abort() 调用
  2. 堆栈展开数据和代码已删除。这节省了一些代码空间,并且可能使编译器的寄存器分配稍微容易一些(但我怀疑它会对性能产生很大影响)。然而,值得注意的是,如果抛出异常,并且库尝试通过 -fno-exceptions 代码展开,它将在此时中止,因为没有展开数据。

这将有效地将所有异常转换为 abort(),如您所愿。但是请注意,您将不允许 throw - 代码中的任何实际 throwcatch 都将导致编译 -时间错误。

选项 #3:(不可移植且不推荐!) Hook __cxa_allocate_exception。

C++ 异常是使用(以及其他)__cxa_allocate_exception 和 __cxa_throw 内部库函数实现的。您可以实现一个 LD_PRELOAD 库,将这些函数与 abort() Hook :

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

警告:这是一个可怕的黑客攻击。它应该适用于 x86 和 x86-64,但我强烈建议不要这样做。值得注意的是,它实际上不会像 -fno-exceptions 那样提高性能或节省代码空间。但是,它将允许 throw syntax,同时将 throws 变成 abort()s。

关于c++ - 禁用 C++ 异常,如何使任何 std::throw() 立即终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7249378/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com