用“-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上。
- 在修改的exception上使用`throw;`
- Pythonexception的最佳实践?
- 我如何编写自定义exception?
- ASP.NET Web API:非描述性500内部服务器错误
- 为什么没有find我自定义的WCF行为扩展元素types?
- Kill(),Environment.Exit(0)或this.Shutdown()
- Exception.getMessage()为null
- 为什么在将客户端JBoss连接回收到远程队列之后仍然抛出SpyJMSExceptionexception?
- 线程“main”中的exceptionjava.lang.UnsupportedClassVersionError:a(Unsupported major.minor version 51.0)