Subject: Re: [boost] [variant2] Formal review
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2019-04-15 20:24:32


On Mon, Apr 15, 2019 at 8:16 AM Andrzej Krzemienski via Boost <
boost_at_[hidden]> wrote:
>
> pon., 15 kwi 2019 o 16:46 Phil Endecott via Boost <boost_at_[hidden]>
> napisał(a):
>
> > Emil Dotchevski wrote:
> > > If the design allows for one more state, then that state must be
handled:
> > > various functions in the program must check "is the object empty" and
> > > define behavior for that case.
> >
> > I think that's often not really the case; at least, it is not a large
> > burden.
> >
> > It seems to me that in many/most cases, the empty state is essentially
> > transient; it can exist between the throw in the assignment and the
> > end of the variant's scope:
> >
> > void f() {
> > variant<...> v{42};
> > v = something; // throw in assignment; v is empty
> > foo(); // skipped
> > blah(); // skipped
> > // v is destructed
> > }
> >
> > You can only observe the empty state if you have a try/catch inside the
> > scope of the variant. Or possibly something with a dtor that accesses
> > the variant. If you limit yourself to not doing that, then you can
> > ignore the possibility of empty in the rest of your logic.
> >
> > What do others think? Do you believe that it would be common to
> > catch the exception thrown during the variant assignment and not
> > "fix up" the variant's value, such that code after the catch could
> > see the variant in its empty state?
> >
>
> "Common" may not be the right word here. If there were practical use cases
> in correct programs that do it that are not common we would have to strive
> even more to address this case. But my position is that programs that
> correctly handle exceptions, and where people understand what a basic
> guarantee is and is not, *never* do this.

>From cppreference: "Basic exception guarantee -- If the function throws an
exception, the program is in a valid state. It may require cleanup, but all
invariants are intact."

"All invariants are intact": f.e. even after std::vector::op= fails, the
target vector is guaranteed to be in a perfectly valid state. By analogy,
the "valueless by exception" state in variant must be a valid state, which
means that various operations may not result in UB even after assignment
failure.