wt., 2 kwi 2019 o 21:31 Emil Dotchevski via Boost
On Tue, Apr 2, 2019 at 11:53 AM Andrzej Krzemienski via Boost < boost@lists.boost.org> wrote:
wt., 2 kwi 2019 o 19:23 Emil Dotchevski via Boost
napisał(a):
On Tue, Apr 2, 2019 at 9:28 AM Andrzej Krzemienski via Boost < boost@lists.boost.org> wrote:
It should be noted that variant2 DOES NOT PROVIDE A STRONG EXCEPTION SAFETY GUARANTEE. The never-empty guarantee has a certain negative effect of confusing people so that they are led to believe that they have
exception safety. But they don't. even expert programmers in this forum expressed their surprise that changing from X to Y in variant
can get them a variant storing Z. Sometimes it is even trickier: X may be a container that currently stores 10 elements. You assign Y, and after exception you get an X that stores zero elements. Because of these problems, the only reasonable thing to do is to follow the advice from Dave Abraham's article: https://www.boost.org/community/exception_safety.html To quote the relevant part, "If a component has many valid states, after an exception we have no idea what state the component is in; only that
state is valid. The options for recovery in this case are limited: either destruction or resetting the component to some known state before further use."
If this principle is followed no-one will ever observe the valueless_by_exception state. This also applies to variant2. If this principle from Dave Abrahams is followed, no-one will ever benefit from the never-empty guarantee (but people will still pay the costs of
it). You cannot do anything meaningful with variant that threw other
destroy or reset it. (But it is probably best to destroy it.) If objects are allowed to survive the stack unwinding, they should either offer a strong exception safety guarantee, or you have to have some very detailed knowledge of a given particular type how its state gets modified under exceptions, but this is usually very difficult and best left to experts.
The argument for a variant type that never ends up in a "valueless" state is not that it is wonderful to deal with objects that change state from X to Y, but that error recovery code is already difficult to write correctly, and while dealing with an object found in a state we didn't leave it in (basic exception safety guarantee) may be annoying, this is preferable
strong the the providing than than
having to deal with objects that explode unless they're destroyed. It's not that programmers "want" to do something with the object other than destroying it, but 1) it is difficult to ensure that this can never ever happen and 2) the way it can be ensured is to sprinkle checks at random places (e.g. where variant asserts are triggered when during error recovery some code happens to touch an object but not destroy it), which is even worse.
Please, illustrate it with an example. Maybe you have some good scenario in mind, but to me, the necessity of sprinkling checks at various places is an indication of a bad approach to exception handling.
Aren't you asking for an example of a destructor that does something other than call other destructors?
Can you show a destructor like that, does a visitatoin on a variant, and that you wouldn't be ashamed to put in your program? Regards, &rzej;