Subject: Re: [boost] [outcome] To variant, or not to variant?
From: Peter Dimov (lists_at_[hidden])
Date: 2017-06-02 16:55:07
Andrzej Krzemienski wrote:
> >> > That's what I was thinking - that you want to place an assert there -
> >> > I just wanted to confirm that this is the only objection.
> >> It is not _the only_ objection. I thought that this one would be the
> >> easiest to communicate across.
> > What are the others?
> In code reviews, when I see someone using the function out of contract, I
> know that this someone has a bug.
But this doesn't apply here, does it?
When you see r->x for !r, you do know that someone has a bug, right?
> > vector::operator accesses occur in tight inner loops, the check is
> > hard to optimize out, so we swallow the UB. Doesn't mean we have to like
> > it, it's a necessary evil here.
> Should I read the above as saying that in case of vector it would cause
> too much potential run-time overhead;
Not merely potential. Actual slowdown on the order of 100. You should read
it as "as much as we'd like to define the behavior of operator, doing so
would be prohibitively expensive, so we won't."
> > > The root of our disagreement is the idea that undefined behavior is
> > > good because it supposedly allows you to do this or that.
> >> It is not in this that I see the root of our disagreement. In fact, I
> >> do not yet see where this root is. What I fight for is not an UB but
> >> narrow contracts.
> > Traditionally the two are synonyms in C++. If you have a narrow
> > contract, the behavior on contract violation is undefined. Can't have
> > one without the other.
> Maybe this calls for a new kind of precondition specification: that
> calling a function in given circumstances is formally incorrect (tools are
> allowed to make use of this information), but the component still
> guarantees a rescue action.
That's kind of what we all want, but there's at present no way of getting
there. Ideally -- let's assume we don't want to allow uses of the form
`r.operator->()` -- we would want `operator->` when `!r` to either invoke a
precondition violation handler that is guaranteed to terminate the program
and never return, or to return `nullptr`.
We have no tradition in expressing the above, so within the current
vocabulary I prefer guaranteeing the `nullptr` instead of leaving the
behavior undefined in the hope that it will end up being defined to the
above. (It won't be.)