C 解析复合赋值中的转换警告

C 解析复合赋值中的转换警告,c,type-conversion,warnings,implicit-conversion,C,Type Conversion,Warnings,Implicit Conversion,在我的代码中,我有很多variable您会收到警告,因为variable根据我对标准的阅读,您无法摆脱此警告,原因如下: uint16_t foo; foo <<= 1; 如果您使用的是32位或64位整数(或任何大于16位的整数)的系统,那么您确实是在将较大的值压入较小的值 解决这一问题的一种方法是明确地使用您的强制类型转换,如下所示: uint16_t foo; foo = (uint16_t)(foo << 1); uint16\u t foo; foo=(uin

在我的代码中,我有很多
variable您会收到警告,因为
variable根据我对标准的阅读,您无法摆脱此警告,原因如下:

uint16_t foo;
foo <<= 1;
如果您使用的是32位或64位整数(或任何大于16位的整数)的系统,那么您确实是在将较大的值压入较小的值

解决这一问题的一种方法是明确地使用您的强制类型转换,如下所示:

uint16_t foo;
foo = (uint16_t)(foo << 1);
uint16\u t foo;

foo=(uint16_t)(foo它们分别是“按位左移位赋值”和“加法赋值”运算符。谢谢。不过我改为“赋值”,所以没有这么复杂的标题:)像这样的所有运算符的名称都是“复合赋值”。太好了,谢谢。更改了标题。您能告诉我您正在使用哪个编译器和哪个标志吗?-说明:它试图用gcc复制警告,但没有成功。我可能完全错了,但这个警告对我来说没有多大意义。毕竟,1没有被分配给“variable”,所以转换为uint16_t对我来说没有意义。1应该被转换成移位的第二个参数是什么类型-我期望int或unsigned int…我所做的实际上是计算CRC,所以我必须使用这些类型。你建议我使用长符号来消除这个警告吗?我也在做其他复合赋值:)没有真正的理由使用
uint16\u t
<代码>未签名
也同样有效。需要时,只需使用
&
%
运算符截断该值。非常好的解释!我刚才也阅读了标准,并同意:它这样说。但我想知道为什么这种转换会发生在逐位移位中。毕竟,移位的值的宽度与指定移位量所需的值的宽度之间没有真正的关系。我的理解是整个提升问题(获取基本原理并阅读关于提升坚毅度的部分)再加上在不能对小于字大小的单元进行位移位的体系结构上需要有一致的行为,这意味着编译器需要自由地只执行字大小的移位/旋转。再加上对一致性的需求,你就会被强制升级位移位操作所困扰。编辑:坦率地说,今天是我第一次有理由阅读《标准》对轮班操作员的看法。我想每天都要学习新东西。你确定非隐式版本是
((unsigned int)foo)
?我倾向于认为它实际上是
int
@cnicutar是正确的,整数提升使它成为
int
,而不是
无符号int
。参见6.3.1.1.2“如果一个int可以表示原始类型的所有值,则该值将转换为int”(同样在C11中)。当然,在这种情况下,int可以表示uint16_t的所有值。另外,请注意,GCC抱怨从“int”转换,而不是从“unsigned int”转换。
uint16_t foo;
foo = foo << 1;
uint16_t foo;
foo = ((int)foo) << 1;
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);