** Thu 17 March 2016
Unsigned integers (size_t
, uint32_t
, and friends) can be hazardous, as
signed-to-unsigned integer conversions can happen without so much as a compiler
warning.
An example: size_t
as an index variable
Occasionally, discussions come up about using unsigned integers as index
variables for STL containers (whose size()
attribute is unsigned). So the
debate is between effectively these two alternatives:
This compiles in gcc with no warnings (unless you set -Wconversion
, but in
general this results in a huge amount of warnings), and the results are not
what you expect:
Since this programmer mistake can happen by accident due to pointer arithmetic errors and other buglets, you’re sometimes looking at a segfault or core dump rather than a more sane error message.
Pedantic note: for platforms with 32-bit int
and concerns about overflows,
substitute int64_t
for the purposes of this discussion.
What to do instead
The Google C++ style guide recommends avoiding unsigned integers except in
situations that definitely require it (for example: file formats often store
sizes in uint32_t
or uint64_t
– no point in wasting a signedness bit that
will never be used).
“In particular, do not use unsigned types to say a number will never be negative. Instead, use assertions for this.” - Google C++ Style Guide
You also do need to be able to check if a variable that should not be
negative ended up being accidentally negative. One approach that many Google
projects (and projects developing in the Google style, like the Apache
incubator projects Impala and Kudu) take is using DCHECK
macros:
These assertions are generally disabled in release builds, but while you are
developing a project in DEBUG
mode (and running your test suite), you get
helpful error messages when you break a “can’t happen” contract without
suffering a performance penalty in production.
Of course, like all things C++-related, this is just my opinion. Feel free to use unsigned integers for function arguments, but they may not buy you the protection from negative numbers that you’re after.