I know, marking a function noexcept
may be useful in order to get many awesome optimizations [in some cases], such as move semantics, for example. But assume, I have a function in my code that does very critical stuff, and, if this function fails, that would mean that something so bad happened that it is impossible to recover, and the program should be terminated immediately. What if I intentionally mark such a function noexcept
even if I admit the probability of exception, just to kill the program if it happens?
Something tells me this is not what it should be used for, but is it a valid use of noexcept
?
CodePudding user response:
This is defined behavior, that's specified in the standard. It is informally described as follows:
Whenever an exception is thrown and the search for a handler encounters the outermost block of a non-throwing function, the function std::terminate is called:
There's even a given example, over there, that does exactly that.
Note that a compiler may issue an advisory diagnostic, if it detects this situation, but this is still well-formed code.
CodePudding user response:
such as move semantics
noexcept
plays no role in move semantics, except that some e.g. containers try to avoid calling non-noexcept
move constructors to provide exception safety guarantees that are otherwise impossible.
something so bad happened that it is impossible to recover, and the program should be terminated immediately.
If an exception isn't caught anywhere up the stack, then this is already exactly what will happen, even if the function is not marked noexcept
(except that stack unwinding may or may not happen). If the exception is caught somewhere up the stack, then presumably it can be handled properly and there is no need to immediately terminate.
And if the cause of the exception itself is so critical that the program cannot continue under any circumstances, then an exception should probably not be thrown in the first place. The program should call std::abort
or something similar right there at the site causing the problem.
But sure, if you think immediate termination is necessary, then mark it noexcept
. I would however still explicitly catch all exceptions with a catch(...)
handler in the function and call std::terminate
or std::abort
manually, so it is clear to a reader and to tools that this is intended behavior. (In this case the stack is unwound up to the handler.)
Is my code ill-formed if I intentionally mark a function [that I know may probably throw] noexcept to terminate immediately in case of exception?
No, letting an exception escape a noexcept
function is perfectly fine. It has defined behavior: std::terminate
will be called to terminate the program via the currently set terminate handler (and also may or may not unwind the stack beforehand, potentially only partially, including up to the noexcept
function).