4

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

#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の値になると思います。 0x43000x0000

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.

何か不足していますか?ありがとう。

4

2 に答える 2

1

私は何が起こっているのか理解しました。最適化はありませんが、crc16を使用しなかったため、セマンティクスが変わったようです。最後に次の行を追加すると、

if (crc16) 
        crc16 = 0x1234;

その場合、crc16 = crc16 << 8;の後に、crc16は期待値(0x4300)になります。

于 2012-04-10T15:20:05.100 に答える