Why int i=400*400/400 gives result 72, is datatype circular?-Collection of common programming errors

The first thing you have to know is, in C, integer overflows are undefined behavior.

(C99, 6.5.5p5) “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.”

C says it very clear and repeats it here:

(C99, 3.4.3p3) “EXAMPLE An example of undefined behavior is the behavior on integer overflow.”

Note that integer overflows only regard signed integer as unsigned integer never overflow:

(C99, 6.2.5p9) “A 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.”

Your declaration is this one:

int i = 400 * 400 / 400;

Assuming int is 16-bit in your platform and the signed representation is two’s complement, 400 * 400 is equal to 160000 which is not representable as an int, INT_MAX value being 32767. We are in presence of an integer overflow and the implementation can do whatever it wants.

Usually, in this specific example, the compiler will do one of the two solutions below:

  1. Consider the overflow wraps around modulo the word size like with unsigned integers then the result of the 400 * 400 / 400 is 72.
  2. Take advantage of the undefined behavior to reduce the expression 400 * 400 / 400 to 400. This is done by good compilers usually when the optimization options are enabled.

Note that that integer overflows are undefined behavior is specific to C language. In most languages (Java for instance) they wrap around modulo the word size like unsigned integers in C.

In gcc to have overflow always wrap, there is the -fno-strict-overflow option that can be enabled (disabled by default). This is for example the choice of the Linux kernel; they compile with this option to avoid bad surprises. But this also constraints the compiler to not perform all optimizations it can do.

Originally posted 2013-11-09 21:02:16.