Boost logo

Boost :

Subject: Re: [boost] [outcome] To variant, or not to variant?
From: Peter Dimov (lists_at_[hidden])
Date: 2017-06-02 12:02:04


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?

> > I can understand the desire to assert() inside, but at the same time,
> > view the idea of returning a X* to something that is not an X ....
>
> Here, the first disagreement. The way I see it is that the blame is on the
> user side. I would put it, "requesting the call X* to something you know
> not to be an X is misguided".

Where is the disagreement? The blame is on the user side. This does not
change what actually transpires.

> > as monumentally misguided in an error handling library.
>
> A question to you. Is your verdict affected by the fact that this is "an
> error handling library" or that this is a "vocabulary type"?

No, this being an error handling library just makes the argument easier.

> In yet other words, do you object the same to vector::operator[] allowing
> UB when over-indexed?

Possibly, today. In the past, not. It depends on whether the optimizer is
good enough to avoid the repeated bounds check, and because of aliasing
concerns, it may not be likely that it will ever be able to optimize it out
in this case.

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.

> I fail to be convinced that "error handling library" should make different
> decisions than any other library.

It shouldn't, I already said the operator-> for smart pointers should behave
the same.

> > The goal here is to help people write robust code,
>
> Here is the second disagreement. That is, I do agree with you (and I guess
> everybody agrees) that this is always the important goal: help people
> write robust code. I just fail to see how the decision to assign *just
> any* semantics to something that is a misguided decision (I mean
> "requesting the call X* to something you know not to be an X") helps
> people write robust code.

"Robust" is not the same as "correct". Robust code means code that doesn't
misbehave when faced with unforeseen circumstances; having a logic error is
such one unforeseen circumstance. Nobody is perfect.

> > not introduce subtle bugs
>
> In general, you cannot protect form users planting bugs in their logic.

And I do not. Accessing a null pointer crashes. I however can mitigate the
effects of their bugs, which is what I'm doing.

> > and security vulnerabilities by allowing them scribble all over the
> > stack.
>
> So, is this your goal? In case the programmer does not know what he is
> doing (that he is using the library incorrectly), the library itself
> should take actions to minimize the damage? I am somewhat convinced by
> that.

Yes, exactly.

Here you have a union of an arbitrary type and std::error_code.
std::error_code contains a pointer to a type with a vtable. Allowing the
ability to write arbitrary data over that pointer is a security concern
because this could lead to arbitrary code execution.

> > (Note that with the above spec, you can still assert in op* and it would
> > be conforming,
>
> Do you mean that you are ok with operator* having a narrow contract?

It already has. I have deliberately left it implicit though.

> And we should also bare in mind Niall's opinion, that if he agrees to a
> narrow contract, such function should spell longer than `value()`.

Yes, there is that.

> > 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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk