下手な英語でごめんなさい。
uint16_t a, c;
uint8_t b = 0xff;
a = b<<8;
c = b*10;
の値とは何a
ですかc
? 任意の整数型の状況とは?
uint16_t a, c;
uint8_t b = 0xff;
a = b<<8;
まず、の引数に対して整数昇格が実行されます<<
。定数8
はanint
であるため、変換されません。の変換ランクは、の変換ランクuint8_t
よりも小さく、のint
すべての値はsuint8_t
として表現できるため、の値を保持して、に変換されます。結果の値は、8ビット左にシフトされます。int
b
int
int
int
が16ビット幅しかない場合、値0xff * 2^8
はとして表現できません。その場合int
、シフトは未定義動作を呼び出します。n1570およびC99では6.5.7(4)です。
E1に符号付きタイプと非負の値があり、E1×2 E2が結果タイプで表現可能である場合、それが結果の値です。それ以外の場合、動作は定義されていません。
それ以外の場合、結果は255*256 = 65280 = 0xFF00
です。その値はのタイプで表現できるため、シフトa
の結果を変換して値を保持します。結果が範囲外の場合(たとえば、シフト距離が9 [および十分に広い]の場合)、からの範囲の値を取得するためにモジュロで削減されます。int
uint16_t
int
2^16
0
2^16 - 1
uint16_t
c = b*10;
通常の算術変換は、のオペランドに対して実行されます*
。両方のオペランドは整数型であるため、最初に整数拡張が実行されます。10
はであり、の型のint
すべての値はb
として表現できるため、int
整数拡張は両方のオペランドに同じ型を与えint
、通常の算術変換ではそれ以上の変換は必要ありません。乗算はタイプで行われint
、その結果は2550
、タイプで再び表現できるため、値をに格納する前にc
変換が行われ、値が保持されます。uint16_t
c
任意の整数型の状況はどうですか?
の場合<<
:
整数プロモーション; int
変換ランクが(および)の整数型以下の整数型の値/式unsigned int
[幅<=
が]の整数型、および(unsigned) int
型のビットフィールドは、またはに変換されます(それがのすべての値を表すことができる場合)元のタイプ、それ以外の場合)。_Bool
int
signed int
unsigned int
int
unsigned int
int
unsigned int
(プロモートされた)右オペランド(シフト距離)が負であるか、(プロモートされた)左オペランドの幅(値ビットと符号ビットの数。符号ビットが1つあるか、まったくない)以上の場合、動作は次のようになります。未定義。(プロモートされた)左オペランドの値が負の場合、動作は未定義です。(プロモートされた)左オペランドのタイプが符号なしの場合、結果はvalue * 2^distance
モジュロを法として減少し2^width
ます。(プロモートされた)左オペランドのタイプが符号付きで、値が非負の場合、結果はvalue * 2^distance
、それがタイプで表現可能である場合、それ以外の場合の動作は未定義です。
2.で未定義の動作が発生しなかった場合、結果は格納されている変数のタイプに変換されます。
_Bool
(またはそのエイリアス)の場合、ゼロ以外の結果は1に変換され、ゼロ以外の結果は0に変換されます。2^width
ます。それ以外の場合、結果はモジュロで減少します。の場合*
:
これが抽象マシンの定義方法です。実装が別の方法で同じ結果(動作が定義されている場合)を達成できる場合は、as-ifルールの下で好きなように実行できます。