wt., 2 kwi 2019 o 19:54 Peter Dimov via Boost
Andrzej Krzemienski wrote:
I have started a thread in this list a while ago, requesting for an example of code that *correctly handles exceptions* (does not stop stack unwinding at random places), where the programmer would make use of the never-empty guarantee , and chose something else than destroying or resetting the variant. And although I received some generic statements, referring to the purity of the design, strength of the invariants, and the easiness of thinking or "correctness", none of the proponents of the never-empty guarantee gave such an example.
template<class T> class monitor { private:
char const* file_; int line_; T const& v_; T old_;
public:
explicit monitor( char const* file, int line, T const& v ): file_( file ), line_( line ), v_( v ), old_( v ) {}
~monitor() { if( v_ != old_ ) { std::clog << file_ << ":" << line_ << ": monitored value changed from " << old_ << " to " << v_ << std::endl; } } };
Thank you. This is the best example I have seen so far.
Or in general, in a destroy-only world, you can never read any values in a destructor or in a function called from a catch clause.
Yes: this seems reasonable, you cannot just call any non-mutating function on a type you do nto know in a piece of the program that is expected not to fail (such as a destructor or scope guard). Similarly, you do not want to invoke arbitrary non-modifying functions in catch clauses on objects that may have suffered from a failure, whose type you do not know and whose invariants can potentially be very "weak". Logging in destructor is risky: you are doing more than cleanup and this can fail on its own. Your example would not compile because variant2 does not provide the streaming operator. Regards, &rzej; It might be an
interesting experiment to make Clang warn on such a use and then try it on some real codebases.
These reads of a potentially-destroy-only values are invisible to you because we don't live in such a world.