根据我对标准的阅读,您无法摆脱此警告,原因如下:
uint16_t foo;
foo <<= 1;
相当于
uint16_t foo;
foo = foo << 1;
然而,这陷入了“整数提升”的世界。
“的价值foo << 1
“表达式的类型为”foo
”,但是在进行左移之前,首先必须经过“整数提升;”部分6.3.1.1.2C99 标准规定:“如果 int 可以表示原始类型的所有值,则将该值转换为 int”。
这使得代码的非隐式版本(带有额外的括号)如下:
uint16_t foo;
foo = ((int)foo) << 1;
考虑到您所在的系统具有 32 位或 64 位整数(或者任何大于 16 位的整数),您确实将较大的值推入较小的值。
解决这个问题的一种方法是明确你的强制转换,如下所示:
uint16_t foo;
foo = (uint16_t)(foo << 1);
但这意味着不,您不能使用较短的按位移位赋值运算符。
如果您确实经常这样做,请考虑创建一个辅助函数,使您的代码清晰并干净地编译。
void LS(uint16_t &value, int shift) { // LS means LeftShift
*value = (uint16_t)(*value << shift);
}
LS(&foo, 1);
TL;DR:不,您不能在使用短运算符的同时避免该警告。