schuppentier
schuppentier

Reputation: 78

What happens when a integer overflow occurs in a C expression?

I have the following C code:

uint8_t firstValue = 111;
uint8_t secondValue = 145;
uint16_t temp = firstValue + secondValue;
if (temp > 0xFF) {
    return true;
}
return false;

This is the alternative implementation:

uint8_t firstValue = 111;
uint8_t secondValue = 145;
if (firstValue + secondValue > 0xFF) {
    return true;
}
return false;

The first example is obvious, the uint16_t type is big enough to contain the result. When I tried the second example with the clang compiler on OS/X, it correctly returned true. What happens there? Is there some sort of temporary, bigger type to contain the result?

Upvotes: 5

Views: 2592

Answers (4)

Pascal Cuoq
Pascal Cuoq

Reputation: 80305

The first example is obvious, the uint16_t type is big enough to contain the result.

In fact the destination lvalue x for the assignment x = expr; has no bearing on whether there is an overflow in expr. If there is, then the result is what it is regardless of how wide x is.

In your example, “integer promotions” apply and the computation is done between int operands. This means that there is no overflow. Integer promotions are described in C11 in clause 6.3.1.1:2.

If you had been adding two uint32_t values, then there could have been wrap-around (the specified behavior when an unsigned operation produces a result that is out of bounds for the unsigned type), even if the type of the lvalue to assign to result to was uint64_t.

Upvotes: 3

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158529

The operands of + are promoted to larger types, we can see this by going to draft C99 standard section 6.5.6 Additive operators which says:

If both operands have arithmetic type, the usual arithmetic conversions are performed on them.

and if we go to 6.3.1.8 Usual arithmetic conversions it says:

Otherwise, the integer promotions are performed on both operands.

and then we go to 6.3.1.1 Boolean, characters, and integers which says (emphasis mine):

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.48) All other types are unchanged by the integer promotions.

So both operands of + in this case will be promoted to type int for the operation, so there is no overflow.

Note, Why must a short be converted to an int before arithmetic operations in C and C++? explains the rationale for promotions.

Upvotes: 8

Jens Gustedt
Jens Gustedt

Reputation: 78943

Yes, all arithmetic is done in a type that has at least the width of int. So your operands are first converted to int and then the operation is performed. As in your first example, the result is then converted back to the target type of the assignment.

Usually it is not a good idea at all to do arithmetic with narrow types. Avoid that when you can, it only complicates things. Best is to avoid these types completely, unless you have a real problem to store large arrays of numbers, e.g.

Upvotes: 2

Soren
Soren

Reputation: 14698

In C, intermediate results are done as at least int, wider if the input type is long or some larger datatype.

Upvotes: 0

Related Questions