Return value of new

Mar 15, 2010 at 2:07am
I always forget this one. I had an interview the other day, and got into a small discussion with the guy about what new returns and when. He said new can always return 0, but I said it will only return 0 if passed std::no_throw. The way exceptions work, wouldn't the stack be unwound in such a way that the return value is never assigned to the pointer, making whatever was supposed to be returned irrelevant, anyway?

PS: No need to mention that there's little point in catching that exception.
Mar 15, 2010 at 2:19am
if new throws an exception, it doesn't return anything. Whatever follows the throw doesn't execute:

1
2
3
4
5
6
int afunc()
{
  throw something;  // function exits here because of the throw

  return 5;  // this is never reached
}
Mar 15, 2010 at 8:18am
new only return 0 in case when its instructed for std::no_throw, in all other case new will throw an exception and will never return in case of throwing exception.
Mar 15, 2010 at 11:19am
helios wrote:
He said new can always return 0, but I said it will only return 0 if passed std::no_throw.


He probably use an environment where an alternative new-handler is installed by default. This happens for some older Visual Studio project settings... (IIRC VS 6.0 and earlier).

Nowadays, the default new handler throws by default.

helios wrote:
wouldn't the stack be unwound in such a way that the return value is never assigned to the pointer

That's correct. The exception stops the excecution before the assignment of any what-so-ever value to anything. If the pointer did not had a value before, it still counts as "uninitialized" and all access to it must be avoided.

1
2
3
4
5
6
int* p;
try { p = new int; } catch (...) {}
// in case of out-of-memory, p will be uninitialized!

p = new (std::nothrow) int;
// p is initialized. Either a pointer or 0 (in case of out-of-memory) 


tajendra wrote:
new only return 0 in case when its instructed for std::no_throw, in all other case new will throw an exception and will never return in case of throwing exception.

Actually new just calls the operator new of the class or the global installed new handler (if no operator new is present). If the global new handler throws bad_alloc (which should be default), so will new.


Oh, by the way.. it's "std::nothrow" not "no_throw".

One more note: Passing std::nothrow does guarantee that new will not throw any exception, not only for the case of out-of-memory. If any installed new-handler throws something else, the program will terminate and not propagate the exception (In other words: operator new(int, nothrow_t&) has a throws() declaration).

Ciao, Imi.
Last edited on Mar 15, 2010 at 11:21am
Mar 15, 2010 at 12:18pm
Oh, by the way.. it's "std::nothrow" not "no_throw".
Whoops.
Topic archived. No new replies allowed.