次のコードを検討してください。
#include <hal_types.h>
int main() {
uint16 crc16; // hal_types.h: typedef unsigned short uint16;
crc16 = 0x43; // debugger: crc16 == 0x0043, as expected
crc16 = crc16 << 8; // crc16 == 0x0000 ????
return 0;
}
このコードは TI CC1111 SoC (8051 コアを搭載) で実行され、最適化なしで C99 方言を使用するように構成された IAR EW8051 8.10.3 を使用してコンパイル/デバッグされています。コメント内の値は、IAR デバッガーで観察されたものです (シミュレーターまたは実際のデバイスを使用した同じ結果)。
aftercrc16 = crc16 << 8;
は ではなくcrc16
の値になると思います。 0x4300
0x0000
C99 標準 (まあ、2005 年 5 月 6 日ドラフト) のセクション 6.5.7.3-4 によると。
整数昇格は各オペランドで実行されます。結果の型は、昇格された左オペランドの型です。右オペランドの値が負の値であるか、プロモートされた左オペランドの幅以上である場合、動作は未定義です。
E1 << E2 の結果は、E1 左シフトされた E2 ビット位置です。空いたビットはゼロで埋められます。E1 が unsigned 型の場合、結果の値は E1 × 2^E2 となり、結果の型で表現可能な最大値より 1 を法として減じられます。E1 に符号付きの型と非負の値があり、E1 × 2^E2 が結果の型で表現できる場合、それが結果の値です。それ以外の場合、動作は未定義です。
これに対する私の見解は、結果の型は符号なしの 16 ビット整数で、値が((0x0043)*(2^8)) % 0x10000 == 0x4300
.
何か不足していますか?ありがとう。