`-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
UNICODE
preprocessor 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]”. ↩︎