On 8/08/2016 01:06, Lorenzo Caminiti wrote:
void fclose(file& f) noexcept { if (!f.is_open()) preconfition_failure_handler(from_function); ...
Where by default the handler terminates:
precondition_failure_handler = [] (from) { std::terminate(); };
But programmers can redefine it to throw (as you suggested above, but beware of what N4160 points out plus on how to program a throwing entry_invariant_failure_handler that shall not throw when from == from_destructor):
precondition_failure_handler = [] (from) { throw failed_precondition(); };
Or to log and exit:
precondition_failure_handler = [] (from) { some-logging-code; exit(-1); };
Or to take any other action programmers wish to take on precondition failure.
It is an error for a noexcept function to call a non-noexcept function outside of a try-catch block. It therefore follows that if precondition_failure_handler is callable in that manner, it must be noexcept, and therefore cannot throw. Otherwise something is fundamentally broken. Whether the caller is a destructor or not is irrelevant; this applies to any noexcept method. Any code that makes special cases for destructors (other than to treat them as noexcept even if not specified) is probably also erroneous. Having said that, there is a small subset of code where it is actually useful to throw from a destructor, though such code needs to be written carefully to avoid problems if called during an unwind.