With "-fno-exceptions", what happens with "new T"?

C++Exception

C++ Problem Overview


I was wondering, will new T still throw bad_alloc if I compile my program using the -fno-exceptions option to disable exception handling?

Or will the compiler (GCC and clang support that option) implicitly transform the use of new T to new (nothrow) T?

C++ Solutions


Solution 1 - C++

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.

So yes, new T will throw an exception, even with -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 right it will call abort() instead.

It seems that, if you want your new T to return NULL on failure, the only way is to explicitely specify nothrow...

Solution 2 - C++

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

[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

Solution 3 - C++

It's not a definitive answer, but the GCC Manual (see the section "Doing Without") has this:

> 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.

The way I read that, you might have to explicitly ask for the nothrow version of new to be completely safe.

Solution 4 - C++

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.

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohannes Schaub - litbView Question on Stackoverflow
Solution 1 - C++Matthijs KooijmanView Answer on Stackoverflow
Solution 2 - C++nosView Answer on Stackoverflow
Solution 3 - C++Michael KristofikView Answer on Stackoverflow
Solution 4 - C++supercatView Answer on Stackoverflow