C および C++ によると、CHAR_BIT >= 8
.
しかし、いつでもCHAR_BIT > 8
,uint8_t
は 8 ビットで表すことさえできません。は、システム上の任意のデータ型の最小ビット数である
ため、より大きくする必要があります。CHAR_BIT
uint8_t
以外のタイプであると法的に定義できるシステムの種類は何unsigned char
ですか?
(C と C++ で答えが異なる場合は、両方を知りたいです。)
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
;と同じ表現である必要はありません。たとえば、ビットは逆の順序で解釈される可能性があります。これはばかげた例ですが、 は 1 の補数または符号の大きさであり、は 2 の補数である必要があるためint8_t
、より理にかなっています。signed char
int8_t
uint8_t
「通常の」システムでも非 char 拡張整数型を使用するもう 1 つの「利点」は、 C のエイリアシング規則です。restrict
文字型は何でもエイリアスすることができます。これにより、キーワードが適切に適用されていない限り、文字ポインターと他の型へのポインターの両方を使用する関数をコンパイラーが大幅に最適化することを防ぎます。ただし、uint8_t
が とまったく同じサイズと表現を持っていてもunsigned char
、実装によってそれが別個の非文字型にされた場合、エイリアシング ルールは適用されず、コンパイラは型uint8_t
およびのオブジェクトがint
、たとえば、エイリアスはありません。
uint8_t
以外のタイプであると法的に定義できるシステムの種類は何unsigned char
ですか?
要約すると、が 8 であるuint8_t
システムでのみ合法的に定義できますCHAR_BIT
。これは、正確に 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 名を定義する必要があります。
「これらのタイプはオプションです」という強調は私のものです。これがお役に立てば幸いです:)
これまで誰も言及していない可能性: if CHAR_BIT==8
and unqualifiedchar
が unsigned である場合、これは一部の ABI にあり、の代わりに のuint8_t
typedef になる可能性があります。これは、オーバーロードの選択 (およびその邪悪な双子である名前マングリング)に影響を与える限り、少なくとも重要です。char
unsigned char
foo(char)
foo(unsigned char)
foo
uint8_t
foo(char)