C++ 使用“-fno-exceptions”,“new T”会发生什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6049563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
With "-fno-exceptions", what happens with "new T"?
提问by Johannes Schaub - litb
I was wondering, will new T
still throw bad_alloc
if I compile my program using the -fno-exceptions
option to disable exception handling?
我想知道,如果我使用禁用异常处理的选项编译我的程序,它new T
仍然会抛出吗?bad_alloc
-fno-exceptions
Or will the compiler (GCC and clang support that option) implicitly transform the use of new T
to new (nothrow) T
?
还是编译器(GCC 和 clang 支持该选项)会隐式转换new T
to的使用new (nothrow) T
?
采纳答案by nos
I can't give a definitive answer to all the perks around -fno-exceptions, just the observations on a 32 bit linux machine, gcc 4.5.1 - bad_alloc is thrown with and without -fno-exceptions
我无法给出关于 -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
回答by Matthijs Kooijman
The way I understand it, operator new
is defined by libstdc++. If you now compile your own code with -fno-exceptions
, you cannot catch any exceptions, but you will still be linking against the normal version of libstdc++, which does throw an exception.
我理解它的方式operator new
是由 libstdc++ 定义的。如果您现在使用 编译您自己的代码-fno-exceptions
,您将无法捕获任何异常,但您仍将链接到 libstdc++ 的正常版本,它确实会引发异常。
So yes, new T
will throw an exception, even with -fno-exception
.
所以是new T
的,即使使用-fno-exception
.
However, if you compiled libstdc++ with -fno-exception
as well, things become different. Now, new T
cannot throw an exception but, if I read the libstdc++ manual rightit will call abort()
instead.
然而,如果你也编译了 libstdc++ -fno-exception
,事情就变得不一样了。现在,new T
不能抛出异常,但是,如果我正确阅读了 libstdc++ 手册,它将abort()
改为调用。
It seems that, if you want your new T
to return NULL on failure, the only way is to explicitely specify nothrow
...
似乎,如果您希望new T
在失败时返回 NULL,唯一的方法是明确指定nothrow
...
回答by Michael Kristofik
It's not a definitive answer, but the GCC Manual(see the section "Doing Without") has this:
这不是一个明确的答案,但GCC 手册(请参阅“没有做”一节)有这个:
Before detailing the library support for
-fno-exceptions
, first a passing note on the things lost when this flag is used: it will break exceptions trying to pass through code compiled with-fno-exceptions
whether or not that code has any try or catch constructs. If you might have some code that throws, you shouldn't use-fno-exceptions
.
在详细介绍对 的库支持之前
-fno-exceptions
,首先要说明使用此标志时丢失的东西:-fno-exceptions
无论该代码是否具有任何 try 或 catch 构造,它都会打破尝试通过编译代码的异常。如果您可能有一些抛出的代码,则不应使用-fno-exceptions
.
The way I read that, you might have to explicitly ask for the nothrow version of new
to be completely safe.
根据我的阅读方式,您可能必须明确要求 的 nothrow 版本new
是完全安全的。
回答by supercat
In many exception-handling systems, if routine "foo" calls "bar", which in turn calls "moo", and "moo" throws an exception, the only way that exception can cleanly make it back to "foo" is if "bar" has code to handle the exception. Even if "bar" is going to let the exception propagate uncaught, it will generally have to ensure that its local variables get properly destroyed before execution is allowed to leave scope. This will require adding extra code to "bar"; in most systems, some of that code will have to execute even if no exception is thrown.
在许多异常处理系统中,如果例程“foo”调用“bar”,后者又调用“moo”,而“moo”抛出异常,则异常可以干净地使其回到“foo”的唯一方法是如果“ bar”具有处理异常的代码。即使“bar”会让异常传播未被捕获,它通常也必须确保在允许执行离开范围之前正确销毁其局部变量。这将需要向“bar”添加额外的代码;在大多数系统中,即使没有抛出异常,其中一些代码也必须执行。
BTW, on some ARM processors like the Cortex M3, or like the Arm7 running in ARM mode, if the caller is also going to be running in ARM mode, one could allow for exceptions without any execution-time cost by having a "normal" subroutine return go to LR+4 (four bytes beyond the normal return address) and have an exceptional exit go to LR (which would then be a 4-byte branch instruction). Such behavior would be contrary to normal practice on the ARM, though, and such a design would not port nicely to the Cortex M0.
顺便说一句,在一些 ARM 处理器上,如 Cortex M3,或像在 ARM 模式下运行的 Arm7,如果调用者也将在 ARM 模式下运行,则可以通过“正常”允许异常而没有任何执行时间成本子程序返回到 LR+4(超出正常返回地址的四个字节)并且有一个异常退出到 LR(这将是一个 4 字节的分支指令)。但是,这种行为与 ARM 上的正常做法背道而驰,而且这种设计不能很好地移植到 Cortex M0。