对建议将 int8_t 的复合赋值提升为 int 的编译器警告感到困惑

发布于 2024-11-04 10:33:00 字数 339 浏览 1 评论 0原文

我通常可以理解编译器警告背后的原因,但这似乎完全是错误的。

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

注定孤独终老 2024-11-11 10:33:00

这就是整数促销在发挥作用。

| 运算符的两个操作数都

x |= y;

提升为 int

x = (int)x | (int)y;

,然后结果转换回 uint8_t,失去精度。

That's integer promotions at work.

in

x |= y;

both operands of the | operator are promoted to int

x = (int)x | (int)y;

then the result is converted back to uint8_t losing precision.

忆离笙 2024-11-11 10:33:00

这是对的。该运算符将参数提升为int。有关更多详细信息,请参阅此页面,第一句开始:

C 不会以比 int [...] 更短的精度进行算术

It is right. The operator promotes the argument(s) to int. See this page for more details, the first sentence begins:

No arithmetic is done by C at a precision shorter than int [...]

虚拟世界 2024-11-11 10:33:00

xy 的值被提升为 int 进行计算,但警告仍然是假的。 | 运算符无法将结果的位宽度增加到超出操作数的宽度,这些操作数已经适合 uint8_t,因为它们是从 uint8_t 提升而来的>。此警告选项标记的绝大多数内容都是完全有效且正确的代码,除非您想在 100 个这样的问题上浪费时间,否则我认为最好关闭或忽略这些警告。

The values of x and y are promoted to int 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 in uint8_t since they were promoted from uint8_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.

别靠近我心 2024-11-11 10:33:00

编译器警告可能看起来很无意义,因为该操作不可能生成超过 8 位的数据,但它只是可以生成超过 8 位数据的较大类操作的子集。例如,如果将 |= 替换为 +=,则溢出的可能性就变得非常现实。

消除警告的方法是告诉编译器您正在有意识地通过强制转换丢弃这些位:

x = (uint8_t)(x | y);

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:

x = (uint8_t)(x | y);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文