https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116342
Bug ID: 116342 Summary: The compiler doesn't respect customised strong_order/weak_order for floating point types. Product: gcc Version: 14.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: daidodo at gmail dot com Target Milestone: --- The following code customises `strong_order` for `float`, but the compiler still uses `std::strong_order`: ``` #include <compare> // Customization for float. // NaN is greater than any other numbers, regardless the sign bit. constexpr std::strong_ordering strong_order(float a, float b) noexcept { if(__builtin_isnan(a)) return __builtin_isnan(b) ? std::strong_ordering::equivalent : std::strong_ordering::greater; if(__builtin_isnan(b)) return std::strong_ordering::less; const auto c = a <=> b; return c < 0 ? std::strong_ordering::less : c > 0 ? std::strong_ordering::greater : std::strong_ordering::equivalent; } int main() { using std::strong_order; constexpr float NEG_NAN = -std::numeric_limits<float>::quiet_NaN(); // Expected, but error static_assert(std::strong_ordering::less == strong_order(3.0f, NEG_NAN)); } ``` I checked the source and believe the problem is in libstdc++-v3/libsupc++/compare (https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/compare#L965). The library makes its own customisation (_S_fp_cmp) and calls it before ADL branch, which means user-defined code will be ignored. The same problem can happen for `weak_order` (https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/compare#L1011), while `partial_order` is fine because it checks ADL at the top. And I think the latest G++ should have the same problem as shown in the latest source. Regards, Zhao