C++ Logo


Advanced search

Re: nullptr_t and nullopt_t should both have operator<=> and operator== to enable the *_with concepts

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Sat, 10 Jul 2021 00:12:01 +0200
On 09/07/2021 23.11, Barry Revzin wrote:
> Third, std::nullptr_t actually did used to have relational operators defined on it. There were two Core Issues (583 and 1512, neither of which mention nullptr), which were resolved by N3478 - but that paper also removed relational comparisons between two nullptrs. What makes this case interesting is that the motivation here was to make "p > nullptr" ill-formed - this isn't the same kind of issue that we have in optional, where "o > nullopt" is fine (if... weird), so while the nullopt comparisons do make things more uniform, since optional<T>(nullopt) == nullopt works so why not just nullopt == nullopt, here we'd be in a case where "nullptr > nullptr" works but not "(T*)nullptr > nullptr". So I don't know how I feel about this case, but regardless of my personal feelings, given that we /did/ have this functionality and it was /explicitly removed/, the paper definitely needs to go into the history of /why/ it was removed and thus why we want to add it back. I've CCed Jens, who
> wrote N3478.

Yeah, I wrote that paper almost a decade ago.

So, this paper made (T*)anything < nullptr
ill-formed, because nullptr cannot ever point to the
same object as the other operand, so this is always
undefined behavior. Flagging this at compile-time is
a good idea. Plus it's consistent with C, as explained

If there is some feeling or use-case that nullptr < nullptr
should be well-formed, that could be proposed. We'd also
need to discuss the (in)consistency with (T*)nullptr < nullptr
and (T*)0 < nullptr. If we want to allow the latter, we're
essentially reverting core issue 583, which we could do,
but that needs a bit of rationale, I'd say.

I feel some sympathy with the idea that single-state types should
behave consistently. However, I've always considered (at least)
nullptr just a special marker and not a real type with a set of
values. For example, it auto-converts to a null pointer of
the "other" type, losing its identity, pretty aggressively.


Received on 2021-07-09 17:12:06