C++:错误:禁用异常处理,使用-fexceptions启用

9

我正在尝试使用-fno-exceptions标志编译简单的代码,但出现了错误。

请告诉我如何抑制这个错误。我正在使用gcc版本4.6.3

代码

#include <iostream>
using namespace std;
int main () {
  try
  {
    throw 20;
  }
  catch (int e)
  {
    cout << "An exception occurred. Exception Nr. " << e << '\n';
  }
  return 0;
}

日志

> g++ throw.cc -o out -fno-exceptions
throw.cc: In function ‘int main()’:
throw.cc:10:11: error: exception handling disabled, use -fexceptions to enable
throw.cc:14:56: error: ‘e’ was not declared in this scope

编辑

我有一个客户端代码,其中有很多类似于这样的异常。我必须将其集成到我的项目中,但我无法控制编译标志来构建(这将来自启用了-fno-exceptions的配置)。我想要一个快速的解决方法,我可以建议。

编辑

我找到了一个解决方法,请参见下面的答案。


7
你的代码明显设计用于捕获异常,为什么你编译时使用了 no-exceptions?为什么不遵循编译器的建议,改为使用 -fexceptions - abelenky
1
这是我编写的一个简单程序,用于说明。我有一个测试设置,使用-fno-exceptions标志和内部使用throw的.so文件。我无法更改我的测试设置中的-fno-exception,因为它不受我控制。我也不能更改.so文件。所以问题是什么? - Kiran
3个回答

18

使用-fno-exceptions标志的程序不能使用异常(try/catch/throw)。

引自gcc手册

在详细介绍支持-fno-exceptions的库之前,首先要注意的是当使用此标志时可能会出现以下问题:它将破坏编译时使用-fno-exceptions的代码中尝试通过的异常,无论该代码是否有任何try或catch结构。如果你可能会有一些抛出异常的代码,就不应该使用-fno-exceptions。如果你有一些使用try或catch的代码,也不应该使用-fno-exceptions。


谢谢,我不知道那个。那么-fno-exceptions在哪里使用呢?只是为了避免像除以0这样的其他代码抛出异常吗?我刚刚看到了文档中的#if __cpp_exceptions

define __try try

define __catch(X) catch(X)

define __throw_exception_again throw

#else

define __try if (true)

define __catch(X) if (false)

define __throw_exception_again

#endif
- Kiran
@Kiran 简单的回答是永远不会。但如果你需要,只能使用不会抛出异常的代码。除以0不是异常情况。请阅读有关此标志的文档。 - ForEveR
我有一个客户端代码,它一直使用异常。我有一个测试设置,其中编译标志设置为-fno-exception,我无法控制那里的标志。我需要将客户端库集成到我的整个项目中。如何处理这种情况? - Kiran
@Kiran,你有两个选择,要么更改客户端,要么更改测试设置。 - molbdnilo
使用-fno-exceptions是一种获得有用分支覆盖数据的方法,参见https://dev59.com/_VgQ5IYBdhLWcg3w7oVA#43726240。 - Roland Sarrazin

5
如果你在自己的代码中抛出异常,就不能使用这个标志编译程序。-fno-exceptions标志会做以下操作
  1. STL库中的所有异常处理都被删除;throws被替换为abort()调用。
  2. 堆栈展开数据和代码被删除。这可以节省一些代码空间,并且可能使编译器更容易进行寄存器分配(但我怀疑它不会有太多性能影响)。值得注意的是,如果抛出异常并且库尝试通过-fno-exceptions代码进行展开,它将在那一点上中止,因为没有展开数据。

这将有效地将所有异常转换为abort(),正如您所希望的那样。然而,请注意,您将不被允许抛出任何实际的throwcatch,否则将导致编译时错误。


5
我找到了一个解决方法。除了catch块中的“e”之外,代码可以重写为:
#include <iostream>
using namespace std;
int main () {
  __try
  {
    __throw_exception_again 20;
  }
  __catch (int e)
  {
    cout << "An exception occurred." << '\n';
  }
  return 0;
}

并且可以使用编译器进行编译。

g++ throw.cc -o out -fno-exceptions.

14
如果CPP异常被禁用,__try__catch是宏,分别转换为if (true)if (false)。因此,在这种情况下,您的try/catch块不起作用。 - ZachB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接