编译器警告说int8t的复合赋值将提升为int,对此感到困惑

puzzled by compiler warning that suggests compound assignment of int8_t promotes to int

本文关键字:int int8t 警告 复合 赋值 编译器      更新时间:2023-10-16

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

#include <stdint.h>    
uint8_t myfunc(uint8_t x,uint8_t y)
{
    x |= y;
    return x;
}

带有-Wall的英特尔编译器抱怨:

conversion from "int" to "uint8_t={unsigned char}" may lose significant bits
  x |= y;
    ^

这是对的吗?上面的代码是不是不可移植和非标准的?

这是integer promotions在工作。

在中

x |= y;

|运算符的两个操作数都提升为int

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

则该结果被转换回失去精度的CCD_ 4。

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

在精度小于int〔…〕的情况下,C无法进行算术运算

xy的值被提升为int用于计算,但警告仍然是假的。|运算符不能将结果的位宽增加到操作数的位宽之外,因为操作数是从uint8_t升级而来的,因此已经适合uint8_t。这个警告选项标志的绝大多数东西都是完全有效和正确的代码,除非你想在100个这样的问题上浪费时间,否则我认为最好关闭或忽略这些警告。

编译器警告可能看起来毫无意义,因为该操作不可能产生超过8个位,但它只是一个更大类操作的子集。例如,如果将|=替换为+=,则溢出的可能性变得非常真实。

消除警告的方法是告诉编译器您有意识地丢弃带有强制转换的位:

x = (uint8_t)(x | y);