13
volatile uint16_t r;
unsigned char poly = 0x07;
unsigned char c = 0;

r = (c << 8) ^ poly;

Linux で gcc を使用してコードをコンパイルするとr7.
同じコードを Microchip C18 でコンパイルするとr0.
なんで?

それを次のように変更すると:

volatile uint16_t r;
uint16_t poly = 0x07;
uint16_t c = 0;

r = (c << 8) ^ poly;

r7もC18になります。

C18 のマニュアルに整数昇格に関するセクションがありますが、私の質問とは関係ないと思います。とにかく、ここにあります:

ISO は、すべての演算を int 精度以上で実行することを義務付けています。デフォルトでは、MPLAB C18 は両方のオペランドが int より小さい場合でも、最大のオペランドのサイズで演算を実行します。ISO で義務付けられている動作は、-Oi コマンドライン オプションを使用して設定できます。

4

2 に答える 2

3

このc << 8コンパイラではが未定義であるため、xorの結果を予測することはできません。結果は、コンパイラーが選択するものであれば何でもかまいません。

未定義動作の概要については、すべてのCプログラマーが未定義動作について知っておくべきこと、特に「特大のシフト量」のセクションを参照してください。

于 2011-05-23T02:09:40.603 に答える
2

c << 8 with ca char は、基本的にすべてのビットを忘却に送ります。ドキュメントで指定されているように、c と 8 の両方が char に収まるため、すべてが char を使用して行われます。

c << 8UL は取引を変更する可能性があります。

于 2011-05-23T00:50:25.317 に答える