Open pkl97 opened 3 weeks ago
@llvm/issue-subscribers-clang-frontend
Author: None (pkl97)
Per the standard, the code is valid and the operator<=>
function is defined as deleted.
If the program is slightly modified to actually use the operator then an error is triggered.
#include <compare>
#include <iostream>
struct C
{
double d1;
double d2;
std::strong_ordering operator<=>(const C&) const = default;
};
int main()
{
const C c1{ .d1=1.0, .d2=2.0 }, c2{ .d1=2.0, .d2=1.0 };
if (c1<c2)
std::cout << "smaller" << std::endl;
return 0;
}
[>>]$ clang++ -std=c++20 -Wall -Wextra main.cpp main.cpp:8:62: error: no matching conversion for static_cast from 'std::partial_ordering' to 'std::strong_ordering' 8 | std::strong_ordering operator<=>(const C&) const = default; | ^ main.cpp:14:11: note: in defaulted three-way comparison operator for 'C' first required here 14 | if (c1<c2) | ^ include/c++/v1/compare/ordering.h:189:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::partial_ordering' to 'const strong_ordering' for 1st argument 189 | class strong_ordering { | ^
~~~~~~ include/c++/v1/__compare/ordering.h:189:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'std::partial_ordering' to 'strong_ordering' for 1st argument 189 | class strong_ordering { | ^~~~~~~ include/c++/v1/compare/ordering.h:192:44: note: candidate constructor not viable: no known conversion from 'std::partial_ordering' to '_OrdResult' for 1st argument 192 | _LIBCPP_HIDE_FROM_ABI explicit constexpr strong_ordering(OrdResult v) noexcept : value(_ValueT(__v)) {} | ^~~~~~~ 1 error generated.
Now the compilation fails with a hint that std::partial_ordering cannot be converted to std::strong_ordering. But there is no explicit error message about operator<=>() being deleted.
Yes, this definitely looks like a bug. Interesting that MSVC seems to have a different bug for the same situation.
This program compiles with clang 19.1.2 but fails to compile with MSVC 19.41:
The MSVC error message:
In my opinion MSVC is correct because double by default only supports std::partial_ordering because of NaN values.
See also here: https://en.cppreference.com/w/cpp/utility/compare/partial_ordering
Why does clang compile the code?