c language · advanced
C: Integer Promotion & Signed/Unsigned
Three C integer rules trip up even experienced engineers. First, the usual arithmetic conversions: when signed and unsigned operands of the same rank are mixed, the signed one is converted to unsigned, so -1 < 1u is FALSE because -1 becomes a huge unsigned value — the classic cause of broken reverse loops over size_t and int-vs-.size() comparisons (compile with -Wsign-compare). Second, integer promotion: operands narrower than int (char, short, bit-fields) are promoted to int before most arithmetic, so char a=200, b=100; computes a+b as int (300) with no char overflow, sizeof(a+b) is sizeof(int), and operators like ~ and << act on the promoted int — promotion happens before the signed/unsigned conversion. Third, overflow asymmetry: unsigned overflow is well-defined modular wraparound, but signed overflow is undefined behavior that the optimizer may assume never occurs (it can even delete an after-the-fact overflow check like if (x+1 < x)), so never rely on signed wrap — use unsigned types, check before operating, or build with -fwrapv / -fsanitize=undefined.
C integer rules: mixing signed/unsigned converts signed to unsigned (-1 < 1u is FALSE); operands smaller than int promote to int before arithmetic (char+char is int math); unsigned overflow wraps (defined) but signed overflow is undefined behavior.
The code
unsigned u = 1;int s = -1;if (s < u) puts("less"); else puts("NOT less"); // prints NOT less!
// s (-1) is converted to unsigned -> 0xFFFFFFFF (huge), so s>u
char a = 200, b = 100;int sum = a + b; // a,b promoted to int BEFORE adding
unsigned char c = 255; c++; // wraps to 0 (defined; unsigned wraps)What this lesson walks through
- 01Usual arithmetic conversions: signed loses to unsigned
- 02Integer promotion: small types become int first
- 03Gotcha — signed/unsigned compares flip
- 04Wraparound: unsigned defined, signed UB
When you mix signed and unsigned of the same rank in an operation, the signed operand is converted to unsigned. So -1 < 1u is FALSE: -1 becomes a huge unsigned value (0xFFFFFFFF), which is greater than 1. This bites loops like for (int i = n-1; i >= 0; i--) when n is unsigned/size_t, and comparisons of int against .size(). Keep index types consistent.
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of C: Integer Promotion & Signed/Unsigned and 100+ animated C++ interview lessons.