`-Wzero-as-null-pointer-constant` vs `std::strong_ordering`
gcc has a warning you can enable: -Wzero-as-null-pointer-constant that seems helpful in
keeping you to the modern C++ guideline to avoid 0 and NULL as “null pointer constants” - see
C++ Guidelines ES.47: Use nullptr rather than 0 or NULL.
But if you try this with -Wzero-as-null-pointer-constant, then simple code such as:
auto test_3way(const int a, const int b) -> int {
std::strong_ordering ordering = a <=> b;
if (ordering == 0) return 0;
return ordering < 0 ? -1 : +1;
}
gives the following errors (I also have -Werror to force all warnings to be errors, otherwise it
would be a warning of course):
sample.cc:36:16: error: zero as null pointer constant [
-Werror=zero-as-null-pointer-constant]
36 | if (ordering == 0) return 0;
| ^
sample.cc:37:18: error: zero as null pointer constant [
-Werror=zero-as-null-pointer-constant]
37 | return ordering < 0 ? -1 : +1;
|
Why is it talking about “null pointer constants” in this vanilla looking code?
Reason is that std::strong_ordering is defined so that you can only compare the four defined constants
(less, equivalent, equal, greater) against 0, not against any other integer. This is an
abstraction designed to encapsulate std::strong_ordering and make it really distinct from just
the (possibly expected) 3-way comparison results -1, 0, and +1. But there’s no real way, without
compiler magic, to restrict the std::strong_ordering comparison operators, at compile time, to comparing
against arbitrary integers. Except for a trick, used by Microsoft (thus MinGW) which was suggested in
the C++ standard1 for 3-way comparison: Use nullptr_t as the type of the second argument of the
comparison, as it’s only two values are nullptr and … 0.
Also, BTW, gcc’s -municode option is broken for console programs
Using -municode which is
described as
It causes the
UNICODEpreprocessor macro to be predefined, and chooses Unicode-capable runtime startup code.
However, it doesn’t work with -mconsole because it doesn’t understand that Unicode-enabled console programs
start at wmain, and it tries to use wWinMain instead (which is for GUI programs).
-
As seen in N4849, the C++ committee’s version of the C++ standard (2020-10-14) - search for the section “[cmp.categories]”. ↩︎