web-dev-qa-db-ja.com

charは正確に8ビット長であることが保証されていますか?

それで全部です。同様のトピックが見つかりませんでしたので、ご了承ください。

59
Ori Popowski

ANSI C仕様のコピー から、セクション3.1.2.5-タイプを参照してください。

Char型として宣言されたオブジェクトは、基本実行文字セットのメンバーを格納するのに十分な大きさです。 $ 2.2.1に列挙されている必要なソース文字セットのメンバーがcharオブジェクトに格納されている場合、その値は正であることが保証されます。他の数量がcharオブジェクトに格納されている場合、動作は実装で定義されます。値は符号付き整数または非負整数として扱われます。

「実行文字セット」の概念は、セクション2.2.1-文字セットで紹介されています。

言い換えると、charは少なくとも、基本実行文字セットを構成する少なくとも95の異なる文字のエンコードを含むのに十分な大きさでなければなりません。

セクションに追加します2.2.4.2-数値制限

適合実装は、ヘッダーで指定されるこのセクションで指定されるすべての制限を文書化しなければならない<limits.h>および<float.h>

整数型のサイズ

以下に示す値は、#ifプリプロセスディレクティブでの使用に適した定数式に置き換えられます。それらの実装定義の値は、同じ符号で示されたものと同じかそれ以上の大きさ(絶対値)でなければなりません。

  • ビットフィールド(バイト)ではない最小のオブジェクトの最大ビット数
    CHAR_BIT 8

  • signed char型のオブジェクトの最小値
    SCHAR_MIN -127

  • signed char型のオブジェクトの最大値
    SCHAR_MAX +127

  • unsigned char型のオブジェクトの最大値
    UCHAR_MAX 255

....

だからあなたはそれを持っている-charのビット数は少なくともでなければなりません8。

47
Paul Dixon

いいえ、8ビットであるとは限りません。 sizeof(char)は1であることが保証されていますが、必ずしも1つの8ビットバイトを意味するわけではありません。

12
anon

いいえ、charデータ型には少なくとも8ビットが含まれている必要があります(ANSI C仕様を参照)

11
dfa

C99標準ドラフトでは、<limits.h>にはマクロが含まれていますCHAR_BITこれは、バイトあたりのビット数を生成し、少なくとも8であることが保証されています(§5.2.4.2.1)。

C++標準ドラフトには、Cの<limits.h>名前の下<climits>(§18.2.2)。

7

標準の正確な内容を見てみましょう:

5.2.4.2.1整数型のサイズ
...
それらの実装定義の値は、同じ符号で示されているものと同じかそれ以上の大きさ(絶対値)でなければなりません。


ビットフィールド(バイト)ではない最小のオブジェクトのビット数
CHAR_BIT 8

これは、バイトが少なくとも8ビットであることを示しています(直前の段落

式で使用されるときにchar型のオブジェクトの値が符号付き整数として扱われる場合、CHAR_MINの値はSCHAR_MINの値と同じになり、CHAR_MAXの値はSCHAR_MAXの値と同じになります。それ以外の場合、CHAR_MINの値は0になり、CHAR_MAXの値はUCHAR_MAXの値と同じになります。値UCHAR_MAXは2 ^ CHAR_BIT-1に等しくなければなりません


各符号付き整数型には、対応する(ただし異なる)符号なし整数型(符号なしのキーワードで指定)があり、同じ量のストレージ(符号情報を含む)を使用し、同じアライメント要件を持っています。


Unsigned char以外の符号なし整数型の場合、オブジェクト表現のビットは、値ビットとパディングビットの2つのグループに分けられます(後者は必要ありません)。

これらの文章は次のことを示しています。

  • 符号なし文字は2 ^ CHAR_BIT-1の値を表す必要があり、最小のCHAR_BITビットでエンコードできます(標準で規定されている従来のビット表現による)
  • 符号なし文字には追加(パディング)ビットが含まれていません
  • 符号付き文字は、符号なし文字とまったく同じスペースを取ります
  • charは、signedまたはunsigned charと同じ方法で実装されます

結論:charとそのバリアントunsigned charとsigned charはサイズが正確に1バイトであることが保証され、バイトは少なくとも8ビット幅であることが保証されます。

今、それらは他の表示です(ただし、上記のような正式な証拠ではありません)、charは実際には1バイトです:

ビットフィールドを除き、オブジェクトは1つ以上のバイトの連続したシーケンスで構成され、その数、順序、およびエンコーディングは、明示的に指定または実装定義されます。


他のオブジェクトタイプの非ビットフィールドオブジェクトに格納される値は、n×CHAR_BITビットで構成されます。nは、そのタイプのオブジェクトのサイズ(バイト単位)です。値はunsigned char型のオブジェクトにコピーできます[n]


Sizeof演算子は、そのオペランドのサイズ(バイト単位)を生成します。これは、式または括弧で囲まれた型の名前です。サイズは、オペランドのタイプから決定されます。結果は整数です。オペランドの型が可変長配列型の場合、オペランドが評価されます。それ以外の場合、オペランドは評価されず、結果は整数定数になります。


Char型、unsigned char型、またはsigned char型(またはその修飾バージョン)のオペランドに適用すると、結果は1になります。配列型のオペランドに適用すると、結果は配列内の合計バイト数になります。 。 88)構造体またはユニオン型を持つオペランドに適用された場合、結果は、内部および末尾の埋め込みを含む、そのようなオブジェクトの合計バイト数になります。

(ここにはあいまいさがあります。sizeof(char)がsizeof(type)ルールをオーバーライドするか、単に例を示しているだけですか?)

それでも、取り組むべき問題が残っています。バイトとは正確には何ですか?規格によれば、「ビットフィールドではない最小のオブジェクト」です。 これは理論的にはマシンバイトに対応しない可能性があることに注意してください。ま​​た、「マシンバイト」と呼ばれるものに関してあいまいさもあります。コンストラクターが「バイト」と呼ぶものは何でも、各コンストラクターが「バイト」の異なる定義を持つ可能性があることを知っている。または、「コンピューターが個々の単位で処理するビットシーケンス」または「アドレス可能な最小データチャンク」などの一般的な定義。

たとえば、7ビットのバイトを持つマシンは、「Cバイト」を2つのマシンバイトとして実装する必要があります。

すべての引用のソース: 委員会ドラフト— 2007年9月7日ISO/IEC 9899:TC

3
Norswap

Limits.hを記述しているC標準から(いくつかの再フォーマットが必要です):

  1. ビットフィールド(バイト)ではない最小のオブジェクトのビット数:CHAR_BIT 8
  2. signed char型のオブジェクトの最小値:SCHAR_MIN -127
  3. signed char型のオブジェクトの最大値:SCHAR_MAX +127

CHAR_BITの最小値8は、文字が少なくとも8ビット幅であることを保証します。 SCHAR_MINおよびSCHAR_MAXの範囲は、符号付き文字の表現が少なくとも8ビットを使用することを保証します。

1
dek