When should std::nothrow be used?
Asked Answered
M

9

34

What is the ideal usage of std::nothrow?

Maddi answered 17/1, 2011 at 21:30 Comment(0)
A
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.

Abutment answered 17/1, 2011 at 21:56 Comment(2)
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.Kneeland
"As far as I'm concerned the days of C++ programs that don't use exceptions at all, are over." Welcome to game development.Azedarach
W
10

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.

Willy answered 17/1, 2011 at 21:37 Comment(6)
Isn't it even simpler to leave them as malloc? Even in C++, malloc does not throw.Abutment
@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.Evocator
@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.Abutment
@Mark: Is there any conceivable reason form malloc and free not to work together? §20.4.6 pretty much they have to...Interdisciplinary
@conio, thanks for the reference. And of course I meant malloc with delete, not malloc with free.Evocator
@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.Abutment
L
9

As I understand it, pretty much never and none.

Linn answered 17/1, 2011 at 21:33 Comment(0)
W
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.)

Wizen answered 17/1, 2011 at 21:37 Comment(0)
L
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.

Lixivium answered 17/1, 2011 at 21:38 Comment(0)
E
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.

Evocator answered 17/1, 2011 at 21:37 Comment(2)
AFAIK it's not microsoft, it's just the way new worked in pre-standard C++ before exceptions were introduced.Depressant
Tizen OS doesn't support the standard exception handling. They use nothrow along with two phase constructor.Nineveh
H
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.

Headword answered 17/1, 2011 at 21:33 Comment(0)
O
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.

Offstage answered 17/1, 2011 at 21:38 Comment(0)
D
-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!

Desulphurize answered 28/8, 2013 at 19:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.