34

What is the ideal usage of std::nothrow?

iammilind
  • 68,093
  • 33
  • 169
  • 336
blitzkriegz
  • 9,258
  • 18
  • 60
  • 71

9 Answers9

12

I'd use it only as an optimization (or code simplification) when I would otherwise have put a try-catch block immediately around a use of regular new, catching std::bad_alloc.

This is quite a rare situation, because it's rare to be able to usefully handle out-of-memory right there at the call site. Usually you allocate memory because you need it, not because you'd quite like to have it but can live without. Code that passes null pointers back up a chain of callers until eventually someone can deal with the problem isn't idiomatic C++.

It can happen though that the error genuinely can be handled immediately. For example you might be in a situation where you'll use one algorithm or technique given sufficient working space, and a different, slower algorithm or technique without. Then again, would you be allocating such working space directly with new? Not normally. And anyway, you sometimes have to be careful with that approach, because if your OS overcommits then in general you cannot handle out of memory gracefully at the application level.

Note that an expression involving std::nothrow can still throw an exception (in particular from any constructor of the object being allocated), so it's only one thing needed if you're hoping to avoid throwing an exception. You also have to ensure that the constructor won't throw.

As far as I'm concerned the days of C++ programs that don't use exceptions at all, are over. I suppose if they resumed for me, due to some particular style guide, then that's the other likely reason for needing nothrow new.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • what does this answer have to do with the question? The question was about std::nothrow and not about methods that do not throw exceptions. – kingston Feb 01 '13 at 12:42
  • "As far as I'm concerned the days of C++ programs that don't use exceptions at all, are over." Welcome to game development. – Tara Nov 30 '19 at 09:08
9

As I understand it, pretty much never and none.

Puppy
  • 144,682
  • 38
  • 256
  • 465
9

Porting a C program to C++. Your C program has all those checks in there, after every malloc, and no notion of exceptions. So it's much simpler to change every malloc to new (nothrow) than to wrap every malloc in a try block.

TonyK
  • 16,761
  • 4
  • 37
  • 72
  • 15
    Isn't it even simpler to leave them as `malloc`? Even in C++, `malloc` does not throw. – Steve Jessop Jan 17 '11 at 21:42
  • @Steve Jessop, is there any guarantee that `malloc` and `free` work together? If not it might be simplest to convert so that you can be consistent. – Mark Ransom Jan 17 '11 at 22:10
  • 4
    @Mark: Not sure what you mean "work together". If the C code doesn't free everything it mallocs, then bugfixing it is separate from porting it. If a C library `malloc` s memory and leaves it to the caller to `free`, then clients of the C++ version might prefer to `delete` instead, *but* by changing the interface in that way you have to make changes to any C++ code that was already using the old C version. I suppose I could agree with the change for that reason, assuming no such existing C++ code. Unpleasant interface, though, there are likely better ways to improve it for the C++ version. – Steve Jessop Jan 17 '11 at 22:20
  • @Mark: Is there any conceivable reason form `malloc` and `free` not to work together? §20.4.6 pretty much they have to... – conio Jan 17 '11 at 22:24
  • 2
    @conio, thanks for the reference. And of course I meant `malloc` with `delete`, not `malloc` with `free`. – Mark Ransom Jan 17 '11 at 22:30
  • @Mark: if accidentally mixing them is the concern, then someone (probably the developer, if not then testers) should use a debugging memory allocator that provides a guarantee `malloc` and `delete` *don't* work together. – Steve Jessop Jan 18 '11 at 13:58
5

Perhaps if your application required nano-optimization and could not allow the overhead of exception handling, then maybe nothrow would be needed.

Bear in mind that Stroustrup is pretty adamant that the programmer can turn off overhead in C++. (As a caveat though, just because you have the choice doesn't mean you should.)

chrisaycock
  • 36,470
  • 14
  • 88
  • 125
4

You use std::nothrow when you want to have to check for null after every new. A lot of legacy code needed it when the first version of the standard was made. A lot of legacy code written afterward use it too because people where paranoid of exceptions. Occasionally you'll run into someone that still is.

It's so very rare that you'd actually want to do this that it even took me a second to remember WTF you were talking about.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
3

I know that there were older versions of C++ (specifically Microsoft's) which did not throw when they could not allocate the memory, but returned NULL instead. This would be an easy way of maintaining compatibility with old code rather than changing all the logic.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 3
    AFAIK it's not microsoft, it's just the way new worked in pre-standard C++ before exceptions were introduced. – Yakov Galka Jan 17 '11 at 22:03
  • Tizen OS doesn't support the standard exception handling. They use nothrow along with two phase constructor. – bikram990 Jun 11 '13 at 04:57
1

http://www.cplusplus.com/reference/std/new/nothrow/

This construction is rarely used, because I suspect that it doesn't really affect the memory allocation performance, rather can be used for convenience.

Still, I the generic variant is usually preferred.

Yippie-Ki-Yay
  • 22,026
  • 26
  • 90
  • 148
1

I can imagine this can be used as a fast-path optimization with custom allocators - say, fail current request and grow the pool at some later/idle time. Pretty much a corner case.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
-2

Only very few programs should ever allocate more than 1 GiB of memory, and since modern systems overcommit memory, new will never return null or throw on these systems. Therefore, there is absolutely no point in checking the return value of new/malloc at all. Just keep your memory footprint down and let the out-of-memory-killer shoot down other processes!

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106