使用" -fno-exceptions","新T"会发生什么?

时间:2011-05-18 18:46:16

标签: c++ exception

我想知道,如果我使用new T选项编译我的程序来禁用异常处理,bad_alloc仍会抛出-fno-exceptions吗?

或者编译器(GCC和clang支持该选项)是否会隐式地将new T的使用转换为new (nothrow) T

4 个答案:

答案 0 :(得分:41)

我理解它的方式,operator new由libstdc ++定义。如果您现在使用-fno-exceptions编译自己的代码,则无法捕获任何异常,但您仍将链接到正常版本的libstdc ++,这会引发异常。

所以是的,即使使用new T-fno-exception也会抛出异常。

但是,如果您使用-fno-exception编译libstdc ++,事情也会变得不同。现在,new T无法抛出异常,但如果我看到the libstdc++ manual right,则会调用abort()

看来,如果您希望new T在失败时返回NULL,唯一的方法是明确指定nothrow ...

答案 1 :(得分:30)

我无法给出围绕-fno-exceptions的所有特权的明确答案,只是对32位linux机器上的观察,gcc 4.5.1 - 带有和不带-fno-exceptions

[21:38:35 1 ~/tmp] $ cat bad_alloc.cpp

int main()
{
    char* c = new char[4000000000U];
}
[21:38:58 1 ~/tmp] $ g++ bad_alloc.cpp
[21:39:06 1 ~/tmp] $ ./a.out
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted
[21:39:07 1 ~/tmp] $ g++ -fno-exceptions bad_alloc.cpp
[21:39:16 1 ~/tmp] $ ./a.out
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted

答案 2 :(得分:9)

这不是一个明确的答案,但GCC Manual(请参阅“不做”一节)有:

  

在详细说明库支持之前   对于-fno-exceptions,首先是过世   注意这个国旗丢失的东西   使用:它将打破异常   试图通过编译的代码   与-fno-exceptions无论是否   该代码有任何尝试或捕获   结构体。如果你可能有一些   抛出的代码,你不应该使用   -fno-exceptions

我读到的方式,您可能必须明确要求new的nothrow版本完全安全。

答案 3 :(得分:0)

在许多异常处理系统中,如果例程“foo”调用“bar”,而“bar”调用“moo”,而“moo”抛出异常,则异常可以干净地将其恢复为“foo”的唯一方法是“bar”是否有代码来处理异常。即使“bar”要让异常传播未被捕获,它通常也必须确保在允许执行离开作用域之前正确销毁其局部变量。这将需要添加额外的代码“bar”;在大多数系统中,即使没有抛出异常,一些代码也必须执行。

BTW,在某些ARM处理器(如Cortex M3)上,或者像在ARM模式下运行的Arm7一样,如果调用者也将在ARM模式下运行,那么可以允许异常,而不需要执行任何时间“normal”子程序返回到LR + 4(超出正常返回地址的四个字节)并有一个异常退出转到LR(这将是一个4字节的分支指令)。但是,这种行为与ARM上的常规做法相反,并且这样的设计不能很好地移植到Cortex M0。