12

通常、コンパイラの警告の背後にある理由は理解できますが、これは明らかに間違っているようです。

#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;
    ^

これは正しいですか?上記のコードは移植性がなく、何らかの形で非標準ですか?

4

4 に答える 4

9

それinteger promotionsは仕事中です。

x |= y;

演算子の両方のオペランド|が昇格されますint

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

その後、結果は変換されuint8_tて精度が失われます。

于 2011-05-03T14:51:24.270 に答える
5

そうです。演算子は、引数を にプロモートしますint。詳細については、このページを参照してください。最初の文は次のように始まります。

int よりも短い精度で C によって演算が行われることはありません [...]

于 2011-05-03T14:49:20.557 に答える
4

xとの値は計算のためyに昇格さintれますが、それでも警告は偽物です。|演算子は、オペランドの幅を超えて結果のビット幅を増やすことはできません。オペランドは からプロモートされたため、すでに収まっていuint8_tますuint8_t。この警告オプションがフラグを立てるもののほとんどは、完全に有効で正しいコードです。このような 100 の質問に時間を無駄にしたくない場合は、これらの警告をオフにするか無視するのが最善だと思います。

于 2011-05-03T14:54:09.820 に答える
1

コンパイラの警告は無意味に思えるかもしれません。なぜなら、演算は 8 ビットを超えて生成できない可能性があるためです。たとえば、 を に置き換えた場合|=+=オーバーフローの可能性が非常に現実的になります。

警告を排除する方法は、キャストを使用して意識的にビットを破棄していることをコンパイラーに伝えることです。

x = (uint8_t)(x | y);
于 2011-05-03T15:19:03.457 に答える