在我的代码中,我有很多variable <<= 1;
个句子,其中variable
的类型为uint16_t。编译器吐出警告说
从'int'转换为'uint16_t'可能会改变其值[-Wconversion]
我该如何解决?我可以使用像variable = (uint16_t)(variable << 1)
这样的长格式符号 - 但我想保留简短的符号。
答案 0 :(得分:5)
根据我对标准的阅读,你不能因为这个原因而放弃这个警告:
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:不,您不能使用短操作符并同时避免该警告。
答案 1 :(得分:1)
您收到警告,因为variable <<= 1;
相当于:
variable = variable << 1;
由于默认的整数提升,右侧的类型为int
,而非uint16_t
。解决此问题的最佳方法是不要使用小于int
类型。