用“-fno-exceptions”,“new T”会发生什么?

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

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

我无法给出一个关于-fno-exceptions的所有特权的明确答案,只是在32位linux机器上的观察,gcc 4.5.1 – bad_alloc被抛出并且没有-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 

我的理解是, operator new是由libstdc ++定义的。 如果现在使用-fno-exceptions编译自己的代码,则不能捕获任何exception,但是仍然会链接到正常版本的libstdc ++,这会引发exception。

所以是的, new T会抛出一个exception,即使是-fno-exception

但是,如果编译libstdc ++时使用了-fno-exception ,则情况会有所不同。 现在, new T不能抛出exception,但是,如果我读了libstdc ++手册,它会调用abort()

看来,如果你想让你的new T在失败时返回NULL,唯一的办法是明确指定nothrow

这不是一个明确的答案,但GCC手册 (见“不做”)部分有这样的:

在详细说明对-fno-exceptions的库支持之前,首先对使用此标志时遗失的东西进行注释:它会打破exception,尝试传递用-fno-exceptions编译的代码,无论代码是否有任何尝试或捕获结构体。 如果你可能有一些代码抛出,你不应该使用-fno-exceptions

我读到的方式,你可能不得不明确要求new版本是完全安全的。

在很多exception处理系统中,如果例程“foo”调用“bar”,又称为“moo”和“moo”,抛出一个exception,exception可以干净地回到“foo”的唯一方法是如果“吧“有代码来处理exception。 即使“bar”会让exception传播未被捕获,通常也必须确保其局部variables在执行被允许离开作用域之前得到适当的销毁。 这将需要添加额外的代码“酒吧”; 在大多数系统中,即使没有抛出exception,也需要执行一些代码。

顺便说一下,在一些像Cortex M3这样的ARM处理器上,或者像在ARM模式下运行的Arm7一样,如果调用者也将在ARM模式下运行,那么可以通过“正常”子程序返回到LR + 4(超出正常返回地址四个字节),并有一个特殊的退出去LR(这将是一个4字节的分支指令)。 但是这样的行为在ARM上会违背正常的实践,而且这样的devise不能很好地转换到Cortex M0上。