私のコードには、uint16_t 型のvariable <<= 1;
文がたくさんあります。variable
コンパイラは警告を吐き出しています
「int」から「uint16_t」への変換により、その値が変更される場合があります [-Wconversion]
どうすれば解決できますか?-のような長い形式の表記を使用することもできますがvariable = (uint16_t)(variable << 1)
、短い表記を維持したいと思います。
私のコードには、uint16_t 型のvariable <<= 1;
文がたくさんあります。variable
コンパイラは警告を吐き出しています
「int」から「uint16_t」への変換により、その値が変更される場合があります [-Wconversion]
どうすれば解決できますか?-のような長い形式の表記を使用することもできますがvariable = (uint16_t)(variable << 1)
、短い表記を維持したいと思います。
標準の私の読書に基づいて、この理由でこの警告から逃れることはできません:
uint16_t foo;
foo <<= 1;
と同等です
uint16_t foo;
foo = foo << 1;
しかし、これは「整数昇格」の世界に巻き込まれています。
foo << 1
" " 式の値の型は " foo
" ですが、左シフトを行う前に、まず「整数昇格」を行う必要があります。C99 標準のセクション6.3.1.1.2では、「int が元の型のすべての値を表すことができる場合、値は int に変換されます」と指定されています。
これにより、コードの非暗黙的なバージョン (追加の括弧付き) が次のようになります。
uint16_t foo;
foo = ((int)foo) << 1;
32 ビットまたは 64 ビット整数 (実際には 16 より大きいもの) を使用しているシステムに警告が表示されている場合、実際には大きな値を小さな値に押し込んでいます。
これを回避する 1 つの方法は、次のようにキャストを明示することです。
uint16_t foo;
foo = (uint16_t)(foo << 1);
しかし、それはいいえ、短いビットごとのシフト代入演算子を使用できないことを意味します。
本当にこれをたくさん行っている場合は、コードを明確にし、きれいにコンパイルするヘルパー関数を作成することを検討してください。
void LS(uint16_t &value, int shift) { // LS means LeftShift
*value = (uint16_t)(*value << shift);
}
LS(&foo, 1);
TL;DR: いいえ、短い演算子を使用すると同時にその警告を回避することはできません。
variable <<= 1;
次と同等であるため、警告が表示されます。
variable = variable << 1;
ここで、デフォルトの整数昇格により、右側の型int
は ではなくです。uint16_t
これを回避する最善の方法は、より小さい型を使用しないことint
です。