In my code I have a lot of variable <<= 1;
sentences where variable
is of type uint16_t. The compiler is spitting a warning saying
conversion to 'uint16_t' from 'int' may alter its value [-Wconversion]
How can I resolve it? I could use a long-form notation like variable = (uint16_t)(variable << 1)
- but I'd like to keep the short notation.
You get the warning because
variable <<= 1;
is equivalent to:where the right-hand side has type
int
, notuint16_t
, due to default integer promotions. The best way around this is not to use smaller-than-int
types.Based upon my reading of the standard, you can not get away from this warning for this reason:
is equivalent to
However, this is caught up in the world of "integer promotion".
The value of the "
foo << 1
" expression has the type of "foo
", however before the left-shift can be conducted it first must go through "integer promotion;" section 6.3.1.1.2 of the C99 standard specifies: "if an int can represent all values of the original type, the value is converted to an int."This makes the non-implicit version of your code (with extra parentheses) as follows:
Given the warning you are on a system with either 32 or 64 bit ints (or anything bigger than 16, really), you are indeed shoving a bigger value into a smaller one.
One way around this is to be explicit with your casts like so:
But that means that no, you can not use the shorter bitwise shift assignment operator.
If you really are doing this a bunch, consider making a helper function that makes your code clear and compiles cleanly.
TL;DR: No, you can't use the short operator and avoid that warning at the same time.