对建议将 int8_t 的复合赋值提升为 int 的编译器警告感到困惑
我通常可以理解编译器警告背后的原因,但这似乎完全是错误的。
#include <stdint.h>
uint8_t myfunc(uint8_t x,uint8_t y)
{
x |= y;
return x;
}
带 -Wall 的 intel 编译器抱怨:
conversion from "int" to "uint8_t={unsigned char}" may lose significant bits
x |= y;
^
这是对的吗?上面的代码是否不可移植且非标准?
I can usually understand the reason behind a compiler warning, but this one seems just plain wrong.
#include <stdint.h>
uint8_t myfunc(uint8_t x,uint8_t y)
{
x |= y;
return x;
}
The intel compiler with -Wall complains:
conversion from "int" to "uint8_t={unsigned char}" may lose significant bits
x |= y;
^
Is this right? Is the above code non-portable and non-standard somehow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这就是
整数促销
在发挥作用。|
运算符的两个操作数都提升为
int
,然后结果转换回
uint8_t
,失去精度。That's
integer promotions
at work.in
both operands of the
|
operator are promoted toint
then the result is converted back to
uint8_t
losing precision.这是对的。该运算符将参数提升为
int
。有关更多详细信息,请参阅此页面,第一句开始:It is right. The operator promotes the argument(s) to
int
. See this page for more details, the first sentence begins:x
和y
的值被提升为int
进行计算,但警告仍然是假的。|
运算符无法将结果的位宽度增加到超出操作数的宽度,这些操作数已经适合uint8_t
,因为它们是从uint8_t
提升而来的>。此警告选项标记的绝大多数内容都是完全有效且正确的代码,除非您想在 100 个这样的问题上浪费时间,否则我认为最好关闭或忽略这些警告。The values of
x
andy
are promoted toint
for the computation, but the warning is nonetheless bogus. The|
operator cannot increase the width in bits of the result beyond the widths of the operands, which already fit inuint8_t
since they were promoted fromuint8_t
. The vast majority of things this warning option flags are completely valid and correct code, and unless you want to waste your time on 100 questions like this, I think it's best to turn off or ignore those warnings.编译器警告可能看起来很无意义,因为该操作不可能生成超过 8 位的数据,但它只是可以生成超过 8 位数据的较大类操作的子集。例如,如果将
|=
替换为+=
,则溢出的可能性就变得非常现实。消除警告的方法是告诉编译器您正在有意识地通过强制转换丢弃这些位:
The compiler warning might seem nonsensical because the operation can't possibly produce more than 8 bits, but it's just a subset of a larger class of operations which can. For example, if you replaced the
|=
with+=
, the possibility of overflow becomes very real.The way to eliminate the warning is to tell the compiler that you're consciously throwing away the bits with a cast: