https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118387

--- Comment #7 from Yihe Li <winmikedows at hotmail dot com> ---
If taken at face value, the standard wording implies that `int operator<=>(...)
= default;` is *never* valid for any class A, since
static_cast<int>(std::strong_ordering::equal) must always be a valid expression
as it is part of the synthesized function body as a fallback, regardless of
whether A has any member.

That is, the following code is still invalid
```cpp
#include <compare>

struct B { int operator<=>(const B&) const; };

struct A
{
    B b;
    int operator<=>(const A&) const = default;
};
```
Even with a B with a compatible return type, the defaulted spaceship in A
should still be ill-formed since the synthesized body is essentially
```cpp
{
    if (auto res = b <=> b; res != 0) return res;
    return static_cast<int>(std::strong_ordering::equal); // <- hard error
}
```
Again (probably for the same reason as the empty case), Clang got this right,
and GCC generated a crash: https://godbolt.org/z/8P3h94GPo

Not sure if this is a conscious design decision or a defect in the standard. If
this is a conscious design decision, then I think it will be much clearer if
the standard directly says "Any defaulted spaceship with return type not
constructible from strong_ordering is ill-formed" after the "If R is auto ..."
case.

Reply via email to