If one makes virtual C++20 three-way comparison operator <=> with the default implementation, then the compiler silently makes one more virtual operator==, as can be shown by overriding it in a child class:
struct A {
virtual std::strong_ordering operator <=>(const A &) const = default;
};
struct B : A {
virtual bool operator==(const A&) const noexcept override;
};
All three major compilers behaves that way, demo: https://gcc.godbolt.org/z/nvaf94M51
Is it mandated by the standard or just a common implementation practice?
As a side observation, in C++20 we also have an ability to make consteval immediate virtual functions, and if the example is extended:
#include <compare>
struct A {
virtual consteval std::strong_ordering operator <=>(const A &) const = default;
};
struct B : A {
virtual consteval bool operator==(const A&) const noexcept override { return false; }
};
int main() {
static constexpr B b;
static constexpr const A & a = b;
static_assert( (a <=> a) == 0 );
static_assert( a != a );
return (a <=> a) == 0;
}
then it introduces certain difficulties to the modern compilers: https://gcc.godbolt.org/z/Gsz39Kr5b
Clang crashes, and GCC produces a program, which fails during execution. Are these just some compiler bugs, or the program is not well formed?