在我的代码中,我有很多类型为 uint16_t 的variable <<= 1;
句子variable
。编译器吐出警告说
从“int”转换为“uint16_t”可能会改变其值 [-Wconversion]
我该如何解决?我可以使用长格式的符号variable = (uint16_t)(variable << 1)
- 但我想保留简短的符号。
在我的代码中,我有很多类型为 uint16_t 的variable <<= 1;
句子variable
。编译器吐出警告说
从“int”转换为“uint16_t”可能会改变其值 [-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:不,您不能同时使用短运算符并避免该警告。
您收到警告,因为variable <<= 1;
相当于:
variable = variable << 1;
由于默认整数促销,右侧有 type int
,而不是。uint16_t
解决这个问题的最好方法是不要使用小于int
类型。