Subject: Re: [boost] [variant2] Andrzej's review
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2019-04-15 10:34:07
sob., 13 kwi 2019 o 07:16 Emil Dotchevski via Boost <boost_at_[hidden]>
> On Fri, Apr 12, 2019 at 9:40 PM degski via Boost <boost_at_[hidden]>
> > On Sat, 13 Apr 2019 at 00:47, Vinnie Falco via Boost <
> > wrote:
> > > If I want/need a variant that offers the never-empty basic guarantee
> > > then Boost should not provide it?
> > >
> > Andrzej argues (in the other post) that you *shouldn't want* it, becoz it
> > masks UB [result of programmer error] and will now cause havoc elsewhere
> > the program.
> The basic guarantee prevents UB, doesn't mask it.
> Perhaps you mean to say "masks bugs", or at least that's how I read
> Andrzej's opinion. This may be so, but I fail to see why the argument
> against the basic guarantee in variant2 assignment does not apply in
> general. It would help me (and perhaps others) understand this argument if
> someone explains why is the basic guarantee appropriate in, say, the
> std::vector<T>::op=, but not in variant.
Let me clarify. I am not arguing against the basic guarantee. (I am all in
favor of basic guarantee.) When I mention a hypothetical variant that
enters a valueless_by_exception state, and later it is UB if its value is
read, I still consider it a basic guarantee. It is just that such type has
a weaker invariant than variant2. It is still considered basic, because you
can perform the minimum set of operations: destroy it and reset it.
My point is:
- The weaker invariant *in the case of variant* does not impose the
additional burden on programmers and does not require of them to put
defensive if-statements before every use of the variant. (Therefore maybe
it is better if this is described by two invariants: one for normal
operations, and one for special-case situations.)
- Basic never empty guarantee is no better than any other basic guarantee.
I never argue that std::vector's invariant should be weaker than what it is
now, because the invariant being stronger than necessary does not cost us
any run-time or spatial performance. It is trivial to provide, does not
increase the size of the vector, it does not require the vector to make
additional allocations, it does not complicate the implementation a single
bit. In fact, it would require efficiency compromises to provide another
"partially defined" state.
However, I still believe that anyone who observes the value of a vector
that threw from its assignment has done their exception handling logic
wrong. And maybe it would be beneficial if in debug mode (or some other
special testing mode) vector contained a flag that it has thrown from any
of its basic-guarantee operations; and an attempt to observe its value
should be signaled with assertion.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk