GCC warns this code:
unsigned char i = 1;
unsigned char j = 2;
i += j;
says:
warning: conversion to 'unsigned char' from 'int' may alter its value [-Wconversion]
i += j;
^
It seems that j
is implicitly converted to int
.
Why the implicit conversion occurs for the addition of same-type variables?
Here's what the C11 draft standard says about (almost) this very case in §5.1.2.3 (page 15):
EXAMPLE 2
In executing the fragment
char c1, c2; /* ... */ c1 = c1 + c2;
the ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to
int
size and then add the twoint
s and truncate the sum. Provided the addition of twochar
s can be done without §5.1.2.3 Environment 15 ISO/IEC 9899:201x Committee Draft — April 12, 2011 N1570 overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions.
So, it's done since the standard requires that it is done. If you look the generated code, it's quite (very) possible that the compiler is clever enough not to do the conversion at all in practice.
C mandates integer promotions, quoting C11 N1570/6.3.1.1p2
The following may be used in an expression wherever an int or unsigned int may be used:
- An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int
So your unsigned char
variable is used in such an expression and as such is converted to int
, since i += j
is functionally equivalent to i = i + j
.
If you know for certain the result is in the range of an unsigned char
, then just apply a cast to the result of the addition before assigning, like this:
i = (unsigned char)(i + j)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With