Subject: Re: [boost] [outcome] To variant, or not to variant?
From: Peter Dimov (lists_at_[hidden])
Date: 2017-06-01 12:15:51
Andrzej Krzemienski wrote:
> > > // *operator->()
> >> > T& operator() & noexcept;
> >> > T const& operator() const & noexcept;
> >> > T&& operator() && noexcept;
> >> > T const&& operator() const && noexcept;
> >> This is operator*, right? This is technically narrow, but without
> >> essential benefits of direct narrow contract, as I tried to explain in
> >> another thread. I disagree.
> > What essential benefits are lost?
> I tried to outline my reasoning in this post:
> In short, when the narrow contract is directly in the library's interface,
> I have a place where I can put BOOST_ASSERT(), or similar code for
> assisting instrumented builds.
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. Do we agree that
returning nullptr from operator-> is good for informing the static analyzer
and the optimizer that a value is present?
r->x; // same as __builtin_assume( has_value() )
X x = *r; // ditto
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 as monumentally
misguided in an error handling library. The goal here is to help people
write robust code, not introduce subtle bugs and security vulnerabilities by
allowing them scribble all over the stack.
(Note that with the above spec, you can still assert in op* and it would be
conforming, and you can still have a mode in which you assert in op->, but
it will not conform.)
The root of our disagreement is the idea that undefined behavior is good
because it supposedly allows you to do this or that. It isn't, it never is.
Defining the good things that we want to happen is good. Not defining them
in the hope they'll occur is not.