
The historical reason for this little quirk in the C standard, is that in the olden days some processors used ones-complement representation for signed numbers, in which case arithmetic for signed and unsigned numbers is slightly different. If you want to be safe, use the -fwrapv compiler flag, which both gcc and clang support this guarantees modulo behavior with all aspects of signed arithmetic.) Symptoms of this behavior can be really tricky to recognize the LLVM website has some explanation of this, along with other bugbears of undefined behavior. (In practice, modern compilers such as gcc and clang tend to use modulo behavior anyway for basic arithmetic calculations, but be careful, as sometimes compiler optimizations will treat comparisons or conditional expressions incorrectly even though the basic arithmetic is "correct". If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.Ī computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type. To would-be language lawyers, the relevant sections in C99 are: If you're programming in C with a compiler that meets the C99 standard, you may be surprised to learn that unsigned integer math is guaranteed to have modulo behavior under overflow conditions, but the behavior of overflow with signed integer math is undefined. Most environments handle overflow gracefully, and give you "wraparound" or "modulo" behavior (32767 + 1 = -32768 in a signed 16-bit environment) where carry bits outside the range just disappear and you're left with the low-order bits corresponding to the exact result. unsigned 32-bit integers support the range Īnd if you go outside this range, even temporarily, you need to be very careful.


signed 32-bit integers support the range.unsigned 16-bit integers support the range.signed 16-bit integers support the range.Each integer format has a representable range:
