Boost logo

Boost :

Subject: Re: [boost] [contract] noexcept and throwing handlers
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2016-08-07 20:22:29


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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk