Signed vs. Unsigned in C/C++

C++There is a little known detail that can ruin a few days of debugging of C code. When you have mixed evaluations with signed and unsigned integers, the signed integers will become unsigned. This rule looks kind of arbitrary, the problem with it being that intuitively we tend to assume that all operands become signed; this is why the next few paragraphs will be sort of shocking.

Let’s take the following straight-forward example:

Let’s see our code work:

Why? As explained, although counter-intuitive, this is what C does. It will interpret -1 as 0xFFFFFFFF unsigned and of course that will be bigger than 0.

What can we do to avoid such issues? As seen above, -Wall does not help us. No warning was issued when compiling a.c, and we were unprepared for this. Instead, to avoid such issues we have to enable the sign-comparison warning by hand, by adding -Wsign-compare. Thus the result:

This may seem like an innocuous warning, but as you seen from the code, it isn’t, and it can generate huge issues.

C++ is stricter in this concern. If you copy the same code under the name and compile it, you get a warning similar with the one above, meaning that the C++ compiler’s version of -Wall is more inclusive. However, the behavior is similar to C’s version behavior.

So be aware of this when mixing sign operands!


Signed vs. Unsigned in C/C++ — 4 Comments