Is std::less supposed to allow comparison of unrelated pointers at compile-time?

I don't think there's a clear answer to the question that you're asking. This is a specific case of LWG 2833: marking a library function constexpr does not explain the circumstances under which calling the function will yield a constant expression.

Until this issue is resolved, I think you simply cannot rely on std::less being able to compare unrelated pointers at compile time.


To be valid constexpr function, it should have parameters for which the result is constexpr, not necessary all parameters.

For example

constexpr int foo(bool b) { if (!b) throw 42; return 42; }

is valid, f(true) can be used in constexpr (even if f(false) cannot).

constexpr int a[2]{};
constexpr bool b = std::less<const void*>{}(&a[0], &a[1]);

is valid and is enough to allow less::operator() to be constexpr.

I don't think it is specified which ranges/values are correct for constexpr in standard.

So all compilers are correct.