Consider the following code:
template class StaticAssert;
template<> class StaticAssert {};
StaticAssert< (-1 < sizeof(in
It's simple and sad. In C/C++:
1U < 2U
(IOW 0U
is the smallest unsigned
value)sizeof
has type size_t
size_t
is an unsigned integer type -1 < 1U
is interpreted as unsigned(-1) < 1U
, and unsigned(-1)
= - 1U
, and obviously - 1U < 1U
, so -1 < 1U
is true.sizeof something
acts (mostly) as an equivalent class (!!!).-1 < sizeof something
The conclusion: this is a design error inherited from C.
Rule:
Only use unsigned types for modular arithmetic, bits manipulations (&
, |
, ^
, <<
, >>
, ~
operators), byte manipulations (unsigned char
means "byte" in C/C++), and characters (unsigned char
means character in C/C++).
Do not use unsigned types to do arithmetic.
If a function expects an integer value that should never be negative, take a signed integer, and optionally check in the function that the value is in range.