Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Never annotate functions involving dynamic memory allocation as noexcept?

Assume you have a function that normally can never fail, for example:

std::string convert_integer_to_string(int x);

In pricipal, this would be a candidate for noexcept. However, the implementation most likely involves involves dynamic memory management, so it could always throw a std::bad_alloc when allocating memory with the new operator.

Is it recommended to annotate the function as noexcept?

From a practical point of view, it is extremely difficult to handle out-of-memory situations in a reasonable way. Most programs just assume that there is enough memory available. Calling std::terminate, as it would happen if a noexcept function throws std::bad_alloc, seems to be reasonable in that case.

For me noexcept is some form of documentation. It is a promise that you (or the optimizer) can safely assume that this function will never throw. If you are programming an application that doesn't care about out-of-memory situations, it is still a valid assumption.

I guess the safest recommendation is to never use noexcept if a std::bad_alloc exception could be thrown. On the other hand, I wonder if there are advantages to use noexcept anyway, assuming that you don't care about out-of-memory situations (i.e., if std::terminate is OK).

like image 599
Philipp Claßen Avatar asked Aug 11 '13 21:08

Philipp Claßen


People also ask

What does Noexcept mean?

The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.

Should I use Noexcept?

In general, you should use noexcept when you think it will actually be useful to do so. Some code will take different paths if is_nothrow_constructible is true for that type. If you're using code that will do that, then feel free to noexcept appropriate constructors.

What does dynamic memory allocation do?

Dynamic memory allocation is the process of assigning the memory space during the execution time or the run time. Reasons and Advantage of allocating memory dynamically: When we do not know how much amount of memory would be needed for the program beforehand.

Can be declared Noexcept?

Function can be declared 'noexcept'. If code isn't supposed to cause any exceptions, it should be marked by using the noexcept specifier. This annotation helps to simplify error handling on the client code side, and enables the compiler to do more optimizations.


1 Answers

I am not sure I'd worry about out of memory exceptions much.

Under some os's (linux at least) the default behaviour when you run out of memory is to be killed by the os (by the oom killer). This happens when you write to the memory (not when you allocate it) and you won't be given a chance to run any cleanup code. This feature is called memory overcommit

Even you do get the information that you've ran out off memory it's pretty hard to deal with those errors properly: you need to make absolutely sure that your exception handler doesn't allocate memory. That includes all the functions you from that error handler, you also need to make sure that any generic exception handler that might have been triggered along the way (e.g. logging) doesn't use any memory. The best you can usually hope for is some simple cleanup before you shut your program down.

Note that you can also use std::nothrow to check the result of an allocation without using exceptions (that is, providing your OS actually tells you that information at allocation time). It might makes sense to do so when you doing a large allocation that you think might fail. This also has the nice property that instead of dealing with (potentially) uncaught exceptions you'll get a nullptr that will be fairly easy to debug.

like image 80
Till Varoquaux Avatar answered Oct 02 '22 23:10

Till Varoquaux