Resolving a conversion warning in a compound assig

2019-07-04 11:42发布

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.

2条回答
小情绪 Triste *
2楼-- · 2019-07-04 12:23

You get the warning because variable <<= 1; is equivalent to:

variable = variable << 1;

where the right-hand side has type int, not uint16_t, due to default integer promotions. The best way around this is not to use smaller-than-int types.

查看更多
干净又极端
3楼-- · 2019-07-04 12:39

Based upon my reading of the standard, you can not get away from this warning for this reason:

uint16_t foo;
foo <<= 1;

is equivalent to

uint16_t foo;
foo = foo << 1;

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:

uint16_t foo;
foo = ((int)foo) << 1;

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:

uint16_t foo;
foo = (uint16_t)(foo << 1);

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.

void LS(uint16_t &value, int shift) {  // LS means LeftShift
  *value = (uint16_t)(*value << shift);
}

LS(&foo, 1);

TL;DR: No, you can't use the short operator and avoid that warning at the same time.

查看更多
登录 后发表回答