web-dev-qa-db-ja.com

uint8_t≠unsigned charはいつですか?

CおよびC++によると、CHAR_BIT >= 8
しかし、CHAR_BIT > 8uint8_tは8ビットで表現することさえできません。
CHAR_BITはシステム上の任意のデータ型の最小ビット数であるため、より大きくする必要があります。

どのようなシステムで、uint8_tunsigned char以外のタイプとして法的に定義できますか?

(CとC++で答えが異なる場合は、両方を知りたいです。)

58
Mehrdad

存在する場合、uint8_tは常にunsigned charと同じ幅でなければなりません。ただし、同じタイプである必要はありません。別個の拡張整数型である場合があります。また、unsigned charと同じ表現である必要はありません。たとえば、ビットは逆の順序で解釈される可能性があります。これは馬鹿げた例ですが、int8_tの方が理にかなっています。signed charは1の補数または符号の大きさですが、int8_tは2の補数である必要があります。

「通常の」システムであっても、uint8_tに非文字拡張整数型を使用することのもう1つの「利点」は、Cのエイリアス規則です。文字型は任意のエイリアスを許可します。これにより、restrictキーワードが適切に適用されない限り、コンパイラが文字ポインタと他の型へのポインタの両方を使用する関数を大幅に最適化できなくなります。ただし、uint8_tunsigned charとまったく同じサイズと表現を持っている場合でも、実装がそれを個別の非文字型にした場合、エイリアス規則は適用されず、コンパイラーは想定できます。たとえば、タイプuint8_tおよびintのオブジェクトは決してエイリアスできません。

56
R..

どのようなシステムで、uint8_tunsigned 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名を定義します。

これらのタイプはオプションです」の強調は私のものです。これがお役に立てば幸いです:)

30
autistic

これまで誰も言及していなかった可能性:CHAR_BIT==8および非修飾charが符号なしで、一部のABIにある場合、uint8_tは代わりにcharのtypedefになります。 unsigned charの。これは少なくとも、オーバーロードの選択(およびその邪悪な双子、名前のマングリング)に影響する限り重要です。つまり、foo(char)foo(unsigned char)の両方をスコープに含める場合、fooを呼び出しますタイプuint8_tの引数は、そのようなシステムでfoo(char)を優先します。

6
zwol