CおよびC++によると、CHAR_BIT >= 8
。
しかし、CHAR_BIT > 8
、uint8_t
は8ビットで表現することさえできません。CHAR_BIT
はシステム上の任意のデータ型の最小ビット数であるため、より大きくする必要があります。
どのようなシステムで、uint8_t
をunsigned char
以外のタイプとして法的に定義できますか?
(CとC++で答えが異なる場合は、両方を知りたいです。)
存在する場合、uint8_t
は常にunsigned char
と同じ幅でなければなりません。ただし、同じタイプである必要はありません。別個の拡張整数型である場合があります。また、unsigned char
と同じ表現である必要はありません。たとえば、ビットは逆の順序で解釈される可能性があります。これは馬鹿げた例ですが、int8_t
の方が理にかなっています。signed char
は1の補数または符号の大きさですが、int8_t
は2の補数である必要があります。
「通常の」システムであっても、uint8_t
に非文字拡張整数型を使用することのもう1つの「利点」は、Cのエイリアス規則です。文字型は任意のエイリアスを許可します。これにより、restrict
キーワードが適切に適用されない限り、コンパイラが文字ポインタと他の型へのポインタの両方を使用する関数を大幅に最適化できなくなります。ただし、uint8_t
がunsigned char
とまったく同じサイズと表現を持っている場合でも、実装がそれを個別の非文字型にした場合、エイリアス規則は適用されず、コンパイラーは想定できます。たとえば、タイプuint8_t
およびint
のオブジェクトは決してエイリアスできません。
どのようなシステムで、
uint8_t
をunsigned char
以外のタイプとして法的に定義できますか?
要約すると、uint8_t
は、CHAR_BIT
が8であるシステムでのみ正当に定義できます。これは、正確に8つの値ビットを持ち、パディングビットがないアドレス指定可能なユニットです。
詳細には、CHAR_BIT
はアドレス可能な最小単位の幅を定義し、uint8_t
はパディングビットを持つことができません。アドレス可能な最小単位が正確に8ビット幅である場合にのみ存在できます。 CHAR_BIT
が8の場合、uint8_t
は、パディングビットを持たない8ビット符号なし整数型の型定義によって定義できます。
C11標準ドラフト(n1570.pdf)の内容は次のとおりです。
5.2.4.2.1整数型のサイズ 1以下に示す値は、#if前処理指令での使用に適した定数式に置き換えられます。 ...それらの実装定義の値は、同じ符号で示されたものと同じかそれ以上の大きさ(絶対値)でなければなりません。
-- number of bits for smallest object that is not a bit-field (byte) CHAR_BIT 8
したがって、最小のオブジェクトには正確にCHAR_BITビットが含まれている必要があります。
6.5.3.4 sizeofおよび_Alignof演算子
...
4 sizeofがchar型、unsigned char型、signed char型(またはその修飾バージョン)のオペランドに適用される場合、結果は1です。
したがって、それらは(一部の)最小のアドレス可能単位です。明らかにint8_t
およびuint8_t
は、存在する限り、最小のアドレス可能ユニットと見なされる場合もあります。
7.20.1.1正確な幅の整数型
1 typedef名intN_tは、幅N、パディングビットなし、2の補数表現を持つ符号付き整数型を指定します。したがって、int8_tは、正確に8ビットの幅を持つ符号付き整数型を示します。
2 typedef名uintN_tは、幅Nでパディングビットのない符号なし整数型を指定します。したがって、uint24_tは、幅がちょうど24ビットのこのような符号なし整数型を示します。
3 これらのタイプはオプションです。ただし、実装が8、16、32、または64ビット幅の整数タイプを提供し、パディングビットがなく、2の補数を持つ(符号付きタイプの場合)表現、対応するtypedef名を定義します。
「これらのタイプはオプションです」の強調は私のものです。これがお役に立てば幸いです:)
これまで誰も言及していなかった可能性:CHAR_BIT==8
および非修飾char
が符号なしで、一部のABIにある場合、uint8_t
は代わりにchar
のtypedefになります。 unsigned char
の。これは少なくとも、オーバーロードの選択(およびその邪悪な双子、名前のマングリング)に影響する限り重要です。つまり、foo(char)
とfoo(unsigned char)
の両方をスコープに含める場合、foo
を呼び出しますタイプuint8_t
の引数は、そのようなシステムでfoo(char)
を優先します。