Never comment on dynamic memory allocation related functions like noexcept?

Suppose you have a function that usually cannot fail, for example:

std::string convert_integer_to_string(int x); 

In the proposal, this will be a candidate for noexcept . However, the implementation most likely includes dynamic memory management, so when allocating memory using the new operator, it can always call std :: bad_alloc .

Is it recommended to annotate a function as noexcept?

From a practical point of view, it is extremely difficult to cope with insufficient memory situations in a reasonable way. Most programs simply assume that there is enough memory. Calling std::terminate , as it would if the noexcept function throws std::bad_alloc , in this case seems reasonable.

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

I believe the safest recommendation is to never use noexcept if the std::bad_alloc exception can be std::bad_alloc . On the other hand, I am wondering if there are any advantages to using noexcept anyway, assuming you are not worried about a memory shortage situation (i.e. if std::terminate is ok).

+6
source share
2 answers

If a function can throw an exception for any reason, even if it is std::bad_alloc , you should not declare it as noexcept . There are relatively few functions that really cannot throw an exception and where it really matters. The primary need for noexcept functions is to allow detection of available error recovery options in the event of an exception: for example, std::vector<T, A> can use the move construct when inserting an object, assuming that the move construct does not throw. If structural movement can be selected, moving objects cannot be used for recovery to exclude when implementing reliable exclusion operations. Thus, if the move construct may fail for type T , then instantiating std::vector<T, A> cannot move the objects, but they need to be copied.

In particular, do not use noexcept as false documentation: this is a violation of the contract if the function can really quit. The fact that the system reacts with a certain level of specific behavior in the event of this violation does not mean that you should use it .... and although simple programs probably will not recover and simply die with out of memory, real programs, at least , you may need to maintain a sufficient condition to restore the disorder that they leave after death, i.e. it is unacceptable for any function to make a decision to kill the program (unless, of course, this is the documented intention of the function).

+9
source

I'm not sure that I will really worry about memory exceptions.

With some os (at least linux) the default behavior, when you run out of memory, os ( oom killer ) should be killed. This happens when you write to memory (and not when it is allocated), and you will not be given a chance to run any kind of cleaning code. This function is called overcommit memory.

Even if you get information that you have run out of memory, it is quite difficult to deal with these errors correctly: you need to absolutely make sure that the exception handler does not allocate memory. This includes all the functions that you use for this error handler, you also need to make sure that any general exception handler that could be run along this path (for example, logging) is not using memory. The best thing you can usually hope for is a simple cleanup before closing the program.

Please note that you can also use std :: nothrow to check the distribution result without using exceptions (that is, providing your OS actually tells you what the information is during distribution). It may make sense to do this when you make a big selection that you think might fail. This also has a nice property that instead of dealing with (potentially) uncaught exceptions, you get nullptr, which will be pretty easy to debug.

+1
source

Source: https://habr.com/ru/post/951513/


All Articles