Gibt es Maschinen, bei denen sizeof (char)! = 1 oder mindestens CHAR_BIT> 8 ist?

93

Gibt es Maschinen (oder Compiler), wo sizeof(char) != 1?

Sagt der C99-Standard , dass sizeof(char)bei der Implementierung der Standardkonformität genau 1 sein muss? Wenn ja, geben Sie mir bitte die Abschnittsnummer und das Zitat.

Update: Wenn ich einen Computer (CPU) habe, der keine Bytes adressieren kann (minimaler Lesevorgang ist 4 Bytes, ausgerichtet), aber nur 4 Bytes ( uint32_t), kann der Compiler für diesen Computer sizeof(char)4 definieren ? sizeof(char)wird 1 sein, aber char wird 32 Bit ( CHAR_BITMakros) haben

Update2: Aber die Größe des Ergebnisses ist KEIN BYTES! es ist die Größe von CHAR. Und char kann 2 Byte oder (möglicherweise) 7 Bit sein?

Update3: Ok. Alle Maschinen haben sizeof(char) == 1. Aber welche Maschinen haben CHAR_BIT > 8?

osgx
quelle
4
Ich mache mir Sorgen um die Einhaltung des C99-Standards. Ich arbeite eng mit C99-Compilern zusammen
osgx
2
Da Unicode noch wichtiger wird, gibt es möglicherweise nicht standardmäßige Compiler, die Unicode-Zeichen als char(anstelle von wchar) verwenden. Selbst wenn der Standard besagt, dass sizeof(char)dies 1 sein muss, würde ich mich nicht auf diese Annahme verlassen.
Chip Uni
14
Es gibt keine C-Compiler, bei denen sizeof (char) nicht 1, Unicode oder nicht ist.
Nr.
6
@Chip: sizeof(char)ist immer 1, auch wenn char 32-Bit ist (wie es auf einigen Systemen der Fall ist). C hat viele lustige Warzen.
Nick Bastin
2
Für alle Versionen des C-Standards muss CHAR_BIT mindestens 8 sein. Sie können CHAR_BIT == 7 nicht haben und standardkonform sein. Es ist jedoch durchaus machbar, dass Maschinen CHAR_BIT> 8 haben. Ich glaube, alte Cray-Maschinen haben dies getan (ich sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int)erinnere mich nicht, ob sizeof(int) == sizeof(long)oder ob CHAR_BIT 32 oder 64 war; ich erwarte, dass es 32 war, und ich denke sizeof(long) == 1auch. (Sie können einen Verweis auf ein Cray C-Handbuch finden, aber keinen Online-Zugriff darauf .)
Jonathan Leffler

Antworten:

91

Es ist immer eins in C99, Abschnitt 6.5.3.4:

Bei Anwendung auf einen Operanden vom Typ char, unsigned char oder signed char (oder einer qualifizierten Version davon) ist das Ergebnis 1.

Bearbeiten: nicht Teil Ihrer Frage, aber aus Interesse von Harbison und Steele, 3. Aufl. (vor c99) p. 148:

Eine Speichereinheit ist die Speichermenge, die von einem Zeichen belegt wird. Die Größe eines Objekts vom Typ charist daher 1.

Bearbeiten: Als Antwort auf Ihre aktualisierte Frage ist die folgende Frage und Antwort von Harbison und Steele relevant (ebenda, Bsp. 4 von Kap. 6):

Ist eine C-Implementierung zulässig, bei der der Typ charWerte zwischen -2.147.483.648 und 2.147.483.647 darstellen kann? Wenn ja, was wäre sizeof(char) unter dieser Implementierung? Was wären die kleinsten und größten Typenbereiche int?

Antwort (ebenda, S. 382):

Es ist zulässig (falls verschwenderisch), dass eine Implementierung 32 Bit zur Darstellung des Typs verwendet char. Unabhängig von der Implementierung ist der Wert von sizeof(char)immer 1.

Dies betrifft zwar nicht speziell einen Fall, in dem beispielsweise Bytes 8 Bit und char4 dieser Bytes sind (mit der c99-Definition tatsächlich unmöglich, siehe unten), die Tatsache, dass dies sizeof(char) = 1immer aus dem c99-Standard und Harbison und Steele hervorgeht.

Edit: In der Tat (dies ist als Antwort auf Ihre upd 2 Frage), soweit c99 angeht sizeof(char) ist in Bytes, aus dem Abschnitt 6.5.3.4 wieder:

Der sizeof-Operator gibt die Größe (in Bytes) seines Operanden an

In Kombination mit dem obigen Zitat sind Bytes mit 8 Bits und char4 dieser Bytes unmöglich: Für c99 ist ein Byte dasselbe wie a char.

Als Antwort auf Ihre Erwähnung der Möglichkeit eines 7-Bit char: Dies ist in c99 nicht möglich. Gemäß Abschnitt 5.2.4.2.1 der Norm beträgt das Minimum 8:

Ihre implementierungsdefinierten Werte müssen gleich oder größer sein [meine Betonung] als die gezeigten mit dem gleichen Vorzeichen.

- Anzahl der Bits für das kleinste Objekt, das kein Bitfeld ist (Byte)

 **CHAR_BIT 8**

- Mindestwert für ein Objekt vom Typ signiertes Zeichen

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

- Maximalwert für ein Objekt vom Typ signiertes Zeichen

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

- Maximalwert für ein Objekt vom Typ vorzeichenloses Zeichen

**UCHAR_MAX 255//28−1** 

- Mindestwert für ein Objekt vom Typ char

**CHAR_MIN**    see below 

- Maximalwert für ein Objekt vom Typ char

**CHAR_MAX**    see below

[...]

Wenn der Wert eines Objekts vom Typ char bei Verwendung in einem Ausdruck als vorzeichenbehaftete Ganzzahl behandelt wird, muss der Wert von CHAR_MIN mit dem von SCHAR_MIN und der Wert von CHAR_MAX mit dem von SCHAR_MAX übereinstimmen. Andernfalls ist der Wert von CHAR_MIN 0 und der Wert von CHAR_MAX der gleiche wie der von UCHAR_MAX. Der Wert UCHAR_MAX muss gleich 2 ^ CHAR_BIT - 1 sein.

Ramashalanka
quelle
9
Zusätzliche Anmerkung. Es gibt ein CHAR_BITS-Makro, das Ihnen sagt, wie viele Bits Ihre Zeichen sind.
Nr.
1
Die vollständigen Daten dieses großartigen Buches stammen von Harbison und Steele. C: Ein Referenzhandbuch, dritte Ausgabe, Prentice Hall, 1991
osgx
2
Wenn Sie wissen, dass Sie mit Zeichentypen arbeiten und die Sprache eine Größe von 1 erfordert, warum ist es eine gute Idee, immer die redundante Größe von (Zeichen) anzugeben?
1
(a) und (c) haben viel schwerwiegendere Konsequenzen, die nicht gelöst werden können oder sogar der Lösung nahe kommen; auch YAGNI. Jemand wie in (b) muss nur einmal informiert werden - ich muss sie nicht in jeder Zeile meines Codes unterrichten. Die Verwendung hat jedoch Nachteile sizeof(char): Es ist ein weiterer Punkt, über den diskutiert / geprüft / etc. Verschwenden Sie in Ihren Codierungskonventionen / -standards / -richtlinien meine Zeit damit, sich zu fragen, ob Sie C wirklich kennen und was sonst möglicherweise falsch ist, und nehmen Sie visuelle / mentale / Textzeilen- "Bandbreite" ein.
1
@ Ramashalanka: Ja, der kompilierte Code ist gleichwertig. Es geht um die Lesbarkeit und darum, wie die Leute den Quellcode verwenden, über den ich spreche. (Und FWIW, ich denke, Sie haben hier eine anständige +1 Antwort. Ich finde nur "immer Größe von (char) verwenden" falsch und ein Hotbutton-Problem für mich, auch wenn es sich um ein kleines Problem handelt.)
21

Es gibt keine Maschinen, auf denen sizeof(char)4 ist. Es ist immer 1 Byte. Dieses Byte kann 32 Bit enthalten, aber für den C-Compiler ist es ein Byte. Für weitere Details werde ich Sie auf die C ++ - FAQ 26.6 verweisen . Dieser Link deckt es ziemlich gut ab und ich bin ziemlich sicher, dass C ++ all diese Regeln von C erhalten hat. Sie können auch in der FAQ 8.10 von comp.lang.c nach Zeichen suchen, die größer als 8 Bit sind.

Upd2: Aber die Größe des Ergebnisses ist KEIN BYTES! es ist die Größe von CHAR. Und char kann 2 Byte oder (möglicherweise) 7 Bit sein?

Ja, es sind Bytes. Lass es mich noch einmal sagen. sizeof(char)ist laut C-Compiler 1 Byte. Was umgangssprachlich ein Byte (8 Bit) genannt wird, ist nicht unbedingt dasselbe wie das, was der C-Compiler ein Byte nennt. Die Anzahl der Bits in einem C-Byte hängt von Ihrer Maschinenarchitektur ab. Es ist auch garantiert mindestens 8.

Michael Kristofik
quelle
3
Bitte!!! C ++ ist die wirklich UNTERSCHIEDLICHE Sprache von C (C99). Diese Frage bezieht sich nur auf einfaches C.
Osgx
<strike> Was kann ich tun, wenn Maschine / CPU nicht auf 8-Bit-Bytes zugreifen kann? Unausgerichteter Zugriff ist verboten. </ Strike> (Auch auf x86 gibt malloc ausgerichtete Daten zurück und weist Speicher in Multiplikationen von 4 Bytes zu.) <Strike> Dann ist CHAT_BIT größer als 8. Ja, eine solche Plattform kann etwas Besonderes sein. </ Strike >
Osgx
10
@osgx, ich neige dazu, genauso viel zu schreien wie du, als die Leute versuchten, C und C ++ zu mischen. Aber ich denke in diesem Fall, dass ein C ++ FAQ-Eintrag genauso gut für C. gilt
Michael Kristofik
3
Der korrekte Name für "8 Bit" ist Oktett. Der C-Standard verwendet das Wort "Byte" für ein Objekt, das die Größe eines Zeichens hat. Andere verwenden das Wort "Byte" möglicherweise auf unterschiedliche Weise, häufig wenn sie "Oktett" bedeuten, aber in C (und C ++ oder Objective-C) bedeutet es "Objekt von der Größe eines Zeichens". Ein Zeichen kann mehr als 8 Bit oder mehr als ein Oktett enthalten, aber es ist immer ein Byte.
Gnasher729
9

PDP-10 und PDP-11 waren.

Update: Es gibt wie keine C99-Compiler für PDP-10.

Einige Modelle von Analog Devices 32-Bit SHARC DSP haben CHAR_BIT = 32, und Texas Instruments DSP von TMS32F28xx haben CHAR_BIT = 16, wie verlautet .

Update: Es gibt GCC 3.2 für PDP-10 mit CHAR_BIT = 9 (überprüfen Sie include / limits.h in diesem Archiv).

osgx
quelle
1
Verwechseln Sie nicht Implementierungen von ähnlichen, aber nicht C-Sprachen wie C. Sie sagten sogar: "Ich mache mir Sorgen um die Einhaltung des C99-Standards. Ich arbeite eng mit C99-Compilern zusammen."
2
@ Roger: Es ist nicht fair, GCC3 als nicht C99-konform zu bezeichnen, es sei denn, Sie haben es mit extremen Randfällen zu tun, die als Fehler in GCC gelten.
Joshua
1
@ Joshua, ich denke Roger sagt über K & R und pcc historische Compiler. Es ist auch nicht fair zu behaupten, dass es C99-konform ist, bevor die C99-Konformitätstestsuite auf PDP-10 ausgeführt wird, wenn es mit diesem Port kompiliert wird (es können Fehler durch Portierung und vom Computer selbst auftreten). Es ist jedoch zu erwarten, dass es dem C99-Standard nahe kommt, ebenso wie GCC3.2 auf x86.
Osgx
1
@Joshua: CHAR_BIT darf in C99 größer als 8 sein, aber sizeof (char) muss immer noch 1 sein (und diese Antwort war sehr unterschiedlich, als ich diesen Kommentar hinterlassen habe). Ich nenne GCC3 nicht nicht konform, und C89 stellt hier die gleiche Anforderung, übrigens. Ich habe diesen Text zitiert, um zu sagen, dass osgx sich Sorgen um die C99-Konformität macht und C99-Compiler verwendet. Warum macht er sich also Sorgen um Nicht-C99-Compiler?
2
Autor von PDP-10 GCC hier. CHAR_BIT ist 9, aber sizeof (char) ist immer noch 1.
Lars Brinkhoff