On Wed, 27 Aug 2025 at 07:33, Tomasz Kamiński <tkami...@redhat.com> wrote:
>
> For any minimum value of a signed type, its negation (with wraparound) results
> in the same value, behaving like zero. Representing the unordered result with
> this minimum value, along with 0 for equal, 1 for greater, and -1 for less
> in partial_ordering, allows its value to be reversed using unary negation:
>   static_cast<unsigned char>(static_cast<unsigned int>(-_M_value))).
> The static casts are required to avoid undefined behavior from signed 
> overflow.

Do we need so many casts? C++20 guarantees two's complement and the
conversion should be well-defined in all cases. We can only have
signed overflow if signed char is the same width as int (which is
never true for any target supported by GCC).

So isn't this equivalent?

return static_cast<__cmp_cat::type>(-_M_value);

-_M_value promotes to int and then there's no UB, because -128 just
becomes 128 which fits in int. The cast back to signed char wraps to
SCHAR_MIN which is the _Unordered value.

We don't even need that static_cast because the conversion to the
return type does the same thing, but it's more explicit and so a bit
clearer.

Reply via email to