Subject: Re: [boost] [variant2] Need rationale for never-empty guarantee
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2019-03-02 08:56:26
sob., 2 mar 2019 o 07:35 Emil Dotchevski via Boost <boost_at_[hidden]>
> On Fri, Mar 1, 2019 at 9:37 PM Andrzej Krzemienski via Boost <
> boost_at_[hidden]> wrote:
> > My hypothesis is that reading valid-but-unspecified can only happen in a
> > buggy program in an unintended path.
> Running out of memory, or out of some other resource, does not indicate a
> bug. In response, under the basic exception guarantee, you may get a state
> which I'm saying shouldn't be merely "destructable" but also valid. For
> example, if this was a vector<T>, it shouldn't explode if you call .size(),
> or if you iterate over whatever elements it ended up with.
This is where my imagination fails me. I cannot imagine why upon bad_alloc
I would be stopping the stack unwinding and determining size of my vectors.
This is why I ask about others' experience with real-world correct code.
> > And that making design compromises to
> > address this path is not necessarily the best approach to take.
> Consider that if you choose to allow, after an error, to have objects left
> in such a state that they may explode if you attempt to do anything but
> destroy them, there may not be any way to detect that state.
Yes. and I do not see how this is a problem in practice. In my experience
objects that failed on operation with basic guarantee can only be safely
removed from the scope. (I do not even reset them.)
> don't want your program to crash, your only choice may be to support this
> as a "valid" state anyway, if not in the object itself, then through some
> external indicator.
I achieve no-UB guarantee by removing objects in "valid but unspecified
state" from scope. I agree: to be able to safely destroy an object you need
some sort of an indicator. A variant may hold it internally and never
expose it. If this is relevant for the sake of the purity of the design, it
can be exposed with member `.valueless_by_exception()` (but it should be UB
if I try to visit such variant). For the sake of the purity of the design
we can call it a normal variant state, as any other state. The fact that
you cannot create this state other than by throwing from operator= and
.emplace() makes a real practical difference.
> It's just better if all elephants you encounter are grey, even if they show
> up where you don't expect them. :)
I sort of understand this point of view. But to me it sounds like an
aesthetic goal rather than a practical or technical one. No real world
example of using "valid but unspecified state" has been shown in this
thread. The arguments put forth use phrases "it is better", "I prefer", "it
is simpler". Normally we do not need to distinguish between aesthetic an
technical goals because in most of the cases they both can be achieved
without compromises. But in case of variant there is a tension/conflict
between aesthetic and technical goals. Maybe this is the root of
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk