sizeof(char)!= 1、または少なくともCHAR_BIT> 8のマシンはありますか?


93

マシン(またはコンパイラ)はどこにありsizeof(char) != 1ますか?

DOES C99標準では、と言っているsizeof(char)標準準拠の実装に正確に1でなければなりませんか?ある場合は、セクション番号と引用を教えてください。

更新: バイト(最小読み取りは4バイト、アラインメント済み)をアドレス指定できないマシン(CPU)があるが、バイトの4秒(uint32_t)のみの場合、このマシンのコンパイラーはsizeof(char)4に定義できますか? sizeof(char)1になりますが、charは32ビットCHAR_BITマクロ)になります

Update2: しかし、sizeof結果はバイトではありません!CHARのサイズです。そしてcharは2バイト、または(多分)7ビットにすることができますか?

Update3:わかりました 。すべてのマシンが持っていsizeof(char) == 1ます。しかし、どのマシンにありCHAR_BIT > 8ますか?


4
C99標準への準拠が心配です。私はC99コンパイラーと緊密に連携しています
osgx

2
Unicodeがさらに重要になると、Unicode文字をchar(ではなくwchar)として使用する非標準のコンパイラが登場する可能性があります。標準sizeof(char)で1 とする必要があると記載されていても、その仮定に依存しません。
チップユニ

14
sizeof(char)が1でないか、UnicodeでないCコンパイラはありません。
nos

6
@Chip:sizeof(char)charが32ビットであっても、常に1です(システムによっては)。Cには楽しいいぼがたくさんあります。
Nick Bastin、2010

2
C標準のすべてのバージョンでは、CHAR_BITが少なくとも8である必要があります。CHAR_BIT == 7にして、標準に準拠させることはできません。しかし、マシンがCHAR_BIT> 8であることは完全に実現可能です。古いCrayマシンはそうだったと思います(sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)それらについて; sizeof(int) == sizeof(long)CHAR_BITが32であったか64であったかを覚えていません。32だったと思いsizeof(long) == 1ますし、私もそう思います。 (Cray Cマニュアルへの参照を見つけることはできますが、オンラインアクセスはできません)
Jonathan Leffler

回答:


91

これは常にC99のセクション6.5.3.4の1つです。

タイプchar、unsigned char、signed char(またはその修飾バージョン)のオペランドに適用すると、結果は1になります。

編集:あなたの質問の一部ではありませんが、ハービソンとスティール、第3版からの興味のために。(c99以前)p。148:

ストレージユニットは、1文字が占めるストレージの量と見なされます。charしたがって、タイプのオブジェクトのサイズは1です。

編集:更新された質問への回答として、ハービソンとスティールからの次の質問と回答が関連しています(同著、第6章の例4):

タイプcharが-2,147,483,648から2,147,483,647の範囲の値を表すことができるCの実装が可能ですか?もしそうなら、sizeof(char) その実装の下には何がありますか?タイプの最小範囲と最大範囲はint何ですか?

回答(同書、p。382):

実装がtypeを表すために32ビットを使用することは(もし無駄であれば)許可されていますchar。実装に関係なく、の値 sizeof(char)は常に1です。

これは、バイトが8ビットでありchar、その4 バイトである場合(c99の定義では実際には不可能、以下を参照)には特に対応していませんsizeof(char) = 1が、c99標準とHarbison and Steeleからは常に明確です。

編集:実際には(これはあなたのUPD 2の質問に対応している)、限りC99が懸念しているようsizeof(char) 、再びセクション6.5.3.4から、バイト単位:

sizeof演算子は、そのオペランドのサイズ(バイト単位)を生成します

したがって、上記の引用と組み合わせると、8ビットのcharバイトがあり、その4バイトは不可能です。c99の場合、バイトはと同じcharです。

7ビットの可能性についてのあなたの言及に答えてchar:これはc99では不可能です。標準のセクション5.2.4.2.1によると、最小値は8です。

それらの実装で定義された値は、表示されている値と同じかそれ以上の大きさ(私の強調点)でなければなりません。

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

 **CHAR_BIT 8**

-符号付き文字型のオブジェクトの最小値

**SCHAR_MIN -127//−(27−1)** 

-符号付き文字型のオブジェクトの最大値

**SCHAR_MAX +127//27−1** 

—タイプunsigned charのオブジェクトの最大値

**UCHAR_MAX 255//28−1** 

— char型のオブジェクトの最小値

**CHAR_MIN**    see below 

— char型のオブジェクトの最大値

**CHAR_MAX**    see below

[...]

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


9
追加のメモ。charのビット数を通知するCHAR_BITSマクロがあります。
nos

1
この素晴らしい本の完全なデータは、ハービソンとスティールのものです。C:リファレンスマニュアル、第3版、プレンティスホール、1991
-osgx 2010

2
char型を使用していて、言語でサイズが1である必要があることがわかっている場合は、冗長なsizeof(char)を常に配置することをお勧めします。

1
(a)と(c)は、これが解決することを期待できない、または解決に近づくことさえできないはるかに深刻な影響を持っています。YAGNIも。(b)のような人は一度だけ教えられる必要があります---私のコードのすべての行でそれらを教える必要はありません。ただし、使用には欠点がありますsizeof(char)。これは、ディベート/チェック/その他の項目です。あなたのコーディング規約/標準/ガイドラインで、あなたが本当にCを知っているかどうか疑問に思っている私の時間を浪費し、他に何が間違っているかもしれないかは、視覚的/精神的/テキスト行の「帯域幅」を占めます。

1
@Ramashalanka:はい、コンパイルされたコードは同等です。私が話しているのは、読みやすさに関する問題であり、そうでなければ、人々がソースコードをどのように使用するかです。(そして、FWIW、私は私はたとえ小さな問題、見当違いと私のためのhotbuttonの問題であることを「常にはsizeof(文字)を使用する」を見つけ、あなたはここにまともな+1の答えを持っていると思います。)

21

sizeof(char)4 のマシンはありません。常に1バイトです。そのバイトには32ビットが含まれる場合がありますが、Cコンパイラに関する限り、それは1バイトです。詳細については、C ++ FAQ 26.6で実際に説明します。そのリンクはそれをかなりカバーしており、C ++がCからそれらのルールをすべて取得したことはかなり確かです。8ビットより大きい文字については、comp.lang.c FAQ 8.10参照することもできます。

Upd2:しかし、sizeofの結果はバイトではありません!CHARのサイズです。そしてcharは2バイト、または(多分)7ビットにすることができますか?

はい、バイトです。もう一度言いましょう。 sizeof(char)Cコンパイラによると1バイトです。人々が口語的にバイト(8ビット)と呼ぶものは、Cコンパイラがバイトと呼ぶものと必ずしも同じではありません。Cバイトのビット数は、マシンアーキテクチャによって異なります。また、少なくとも8であることが保証されています。


3
お願いします!!!C ++は、C(C99)とはまったく異なる言語です。この質問は、プレーンCについてのみです。
osgx 2010

<strike>マシン/ CPUが8ビットバイトにアクセスできない場合、どうすればよいですか?アライメントされていないアクセスは禁止されています。</ strike>(x86でも、mallocはアライメントされたデータを返し、メモリを4バイトの倍数で割り当てます。)<strike>その場合、CHAT_BITは8より大きくなります。はい、このようなプラットフォームはかなり特殊な場合があります。</ strike >
osgx 2010

10
@osgx、私は人々がCとC ++を混合しようとしたときと同じくらい悲鳴を上げる傾向があります。しかし、私が思うに、この場合には 1つのC ++ FAQエントリはC.にも同様に適用されること
マイケルKristofik

3
「8ビット」の正しい名前はオクテットです。C標準では、文字のサイズであるオブジェクトに「バイト」という単語を使用しています。他の人は、「バイト」という単語をさまざまな方法で使用しますが、多くの場合、「オクテット」を意味しますが、C(およびC ++、またはObjective-C)では「オブジェクトのサイズ」を意味します。charは8ビットを超える場合もあれば、1オクテットを超える場合もありますが、常に1バイトです。
gnasher729 2014

9

PDP-10 とPDP-11はそうでした。

更新:PDP-10用のC99コンパイラはないようです。

アナログデバイスの32ビットSHARC DSPの一部のモデルにはCHAR_BIT = 32があり、TMS32F28xxのTexas Instruments DSPにはCHAR_BIT = 16があると報告されています。

更新:CHAR_BIT = 9のPDP-10用のGCC 3.2があります(そのアーカイブのinclude / limits.hを確認してください)。


1
Cと類似しているがCではない言語の実装を混同しないでください。「C99標準への準拠に不安があります。C99コンパイラと緊密に連携しています」とさえ言っていました。

2
@Roger:GCCのバグと見なされる極端なエッジケースを扱っていない限り、C99に準拠していないGCC3を呼び出すことは公平ではありません。
ジョシュア

1
@ジョシュア、私はロジャーがK&Rとpccの歴史的なコンパイラについて言っていると思います。また、このポートでコンパイルした場合、PDP-10でC99準拠のテストスイートを実行する前に、C99準拠と主張するのは不公平です(移植およびマシン自体からのバグが存在する可能性があります)。ただし、x86上のGCC3.2と同様に、C99標準に近いと予想できます。
osgx

1
@ジョシュア:C99では、CHAR_BITを8より大きくすることができますが、sizeof(char)は1である必要があります(このコメントを残したとき、この答えは大きく異なりました)。私はGCC3を非準拠とは呼んでおらず、C89もここで同じ要件を課しています。osgxはC99準拠が心配され、C99コンパイラを使用していると言うためにそのテキストを引用しましたが、なぜ彼はC99以外のコンパイラを心配しているのですか?

2
PDP-10 GCCの著者はこちら。CHAR_BITは9であるが、はsizeof(チャー)は依然として1である
ラースBrinkhoffに
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.