4

次のコードを検討してください。

uint16_t a = ~ ( uint16_t ) 0;
int16_t  b = ~ ( int16_t ) 0;
printf (
    "%d %d %d %d\n",
    a  == ~ ( uint16_t ) 0,
    a  == ( uint16_t ) ( ~ ( uint16_t ) 0 ),
    b  == ~ ( int16_t ) 0,
    b  == ( int16_t ) ( ~ ( int16_t ) 0 )
);

出力は次のとおりです。

0 1 1 1

GCC は次の警告をスローしますa == ~ ( uint16_t ) 0

データ型の範囲が制限されているため、比較は常に false [-Wtype-limits]

ビットごとの「not」演算子が符号付きの値を返そうとしているのはなぜですか? どうすればそれを防ぐことができますか?

4

2 に答える 2

9

ビットごとの「not」演算子が符号付きの値を返そうとしているのはなぜですか?

よりも小さい型では演算子が機能しないためintです。小さい型 ( 16 ビットを超えるuint16_t場合を含む) は、オペランドとして使用すると昇格されます。ここにあるように、元の型のすべての値が で表現できる場合、昇格は になります。intintint

どうすればそれを防ぐことができますか?

できません; それが言語の仕組みです。aを初期化するときのように暗黙的に、またはキャストを使用して明示的に、演算子の結果を必要な型に変換する必要があります。適用するにキャストする必要がないことに注意してください~。ただし、移植性を最大限に高めるために、ビットごとのロジックを実行するときは符号なしの型に固執する必要があります。

uint16_t a = ~0u;
printf("%d\n", a == (uint16_t)~0u);  // Should print 1
于 2013-05-11T12:01:47.467 に答える