Subject: Re: [boost] [outcome] To variant, or not to variant?
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-06-01 23:38:09
On 2/06/2017 00:15, Peter Dimov 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. Do we agree that
> returning nullptr from operator-> is good for informing the static
> analyzer and the optimizer that a value is present?
I assume you meant "not present" there.
Having an explicit assert is still probably better than just returning
nullptr and hoping for a static analyzer to pick up on that (or to crash
at runtime). There are some platforms where unfortunately addresses
around zero are valid (and while the standards allow the compiler to
make nullptr not zero in this case, I don't know of any compilers that
actually do so, probably because it's hard to actually do that alongside
code that assumes it can memset(0) to get null pointers).
I think the assert should be in there regardless; so then the question
becomes whether you just reinterpret_cast<> after that or if you check
type and return nullptr if you somehow survive the assert.
It's not even really a narrow vs. wide contract thing, because it's
never well-defined behaviour for -> to return nullptr.
If assertions are disabled then both of these behaviours are UB (since
returning nullptr from -> will result in dereferencing nullptr, which is
inherently UB), but the second one is at least more likely to crash on
those platforms that don't have valid memory around 0, and that's a good
On the other hand, some people would argue that the extra branch is
pointless, especially in contexts where you check up front once and then
use -> multiple times, which is not an uncommon pattern. (Sure, you
could use * once and capture a reference, then avoid the issue entirely,
but that can make the code look more awkward.)