在我的代码中有很多 variable <<= 1;
哪里的句子variable
是 uint16_t 类型。编译器发出警告说
conversion to 'uint16_t' from 'int' may alter its value [-Wconversion]
我该如何解决?我可以使用像 variable = (uint16_t)(variable << 1)
这样的长格式符号- 但我想保留简短的符号。
最佳答案
根据我对标准的阅读,你无法摆脱这个警告:
uint16_t foo;
foo <<= 1;
相当于
uint16_t foo;
foo = foo << 1;
然而,这陷入了“整数提升”的世界。
“foo << 1
”表达式的值具有“foo
”的类型,但是在进行左移之前,它首先必须经过“整数提升”; C99 标准的 6.3.1.1.2 部分规定:“如果一个 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:不,您不能在使用短运算符的同时避免该警告。
关于c - 解决复合分配中的转换警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18629780/