Welche Plattformen haben etwas anderes als 8-Bit-Zeichen?
Lesezeit: 10 Minuten
Craig McQueen
Hin und wieder weist jemand auf SO darauf hin char (auch bekannt als ‘Byte’) ist nicht unbedingt 8 Bit.
Es scheint, dass 8-Bit char ist fast universell. Ich hätte gedacht, dass es für Mainstream-Plattformen notwendig ist, 8-Bit zu haben char um seine Lebensfähigkeit auf dem Markt sicherzustellen.
Sowohl heute als auch in der Vergangenheit, welche Plattformen verwenden a char das sind keine 8 Bit, und warum sollten sie sich von den “normalen” 8 Bit unterscheiden?
Wenn Sie Code schreiben und über plattformübergreifende Unterstützung nachdenken (z. B. für allgemein verwendbare Bibliotheken), welche Art von Überlegung lohnt es sich, Plattformen mit Nicht-8-Bit zu geben char?
In der Vergangenheit bin ich auf einige DSPs von Analog Devices gestoßen, für die char ist 16 Bit. DSPs sind eine Art Nischenarchitektur, nehme ich an. (Andererseits schlug handcodierter Assembler leicht, was die verfügbaren C-Compiler konnten, also habe ich nicht wirklich viel Erfahrung mit C auf dieser Plattform gesammelt.)
Die CDC Cyber-Serie hatte eine 6/12-Bit-Codierung. Die beliebtesten Zeichen waren 6 Bit. Die restlichen Zeichen verwendeten 12 Bit.
– Thomas Matthäus
20. Januar 2010 um 0:07 Uhr
Der PDP-11 hat es auf den Punkt gebracht. Die Vorstellung, dass ein Zeichen in einem Zeichen kodiert werden kann, ist ernsthaft veraltet.
– Hans Passant
20. Januar 2010 um 1:38 Uhr
“Der PDP-11 hat es geschafft” – Sie meinen, weil C zuerst für den PDP-11 mit 8-Bit-Bytes implementiert wurde? Aber C wurde als nächstes für Honeywell-Maschinen mit 9-Bit-Bytes implementiert. Siehe K&R Version 1. Außerdem wurde die Frage nach char (dh byte) und nicht nach character gestellt (ein oder mehrere Bytes codieren etwas, nach dem nicht gefragt wurde).
– Windows-Programmierer
20. Januar 2010 um 3:40 Uhr
DEC-10 und DEC-20 hatten 36-Bit-Wörter. Fünf 7-Bit-ASCII-Zeichen pro Wort waren durchaus üblich. Außerdem wurden sechs 6-Bit-Zeichen verwendet.
– David R. Tribble
20. Januar 2010 um 17:12 Uhr
@CraigMcQueen: Wenn ich mich richtig erinnere, lässt CodeVision für Atmel-Mikrocontroller die Größe von char wählen
– vsz
20. Februar 2016 um 10:10 Uhr
Steve Jessop
char ist auch 16 Bit auf den Texas Instruments C54x DSPs, die zum Beispiel in OMAP2 auftauchten. Es gibt andere DSPs mit 16 und 32 Bit char. Ich glaube, ich habe sogar von einem 24-Bit-DSP gehört, aber ich kann mich nicht erinnern, was, also habe ich es mir vielleicht eingebildet.
Eine weitere Überlegung sind die POSIX-Mandate CHAR_BIT == 8. Wenn Sie also POSIX verwenden, können Sie davon ausgehen. Wenn später jemand Ihren Code auf eine Beinahe-Implementierung von POSIX portieren muss, hat das zufälligerweise die von Ihnen verwendeten Funktionen, aber eine andere Größe chardas ist ihr Pech.
Im Allgemeinen denke ich jedoch, dass es fast immer einfacher ist, das Problem zu umgehen, als darüber nachzudenken. Tipp einfach CHAR_BIT. Wenn Sie einen exakten 8-Bit-Typ wünschen, verwenden Sie int8_t. Ihr Code wird bei Implementierungen, die keine bereitstellen, lautstark nicht kompiliert, anstatt stillschweigend eine Größe zu verwenden, die Sie nicht erwartet haben. Wenn ich auf einen Fall stoße, in dem ich einen guten Grund hätte, es anzunehmen, würde ich es zumindest behaupten.
TI C62xx- und C64xx-DSPs haben auch 16-Bit-Zeichen. (uint8_t ist auf dieser Plattform nicht definiert.)
– myron-semack
20. Januar 2010 um 2:35 Uhr
Viele DSPs für die Audioverarbeitung sind 24-Bit-Maschinen; der Bela Signa DSPs von On Semi (nachdem sie AMI Semi gekauft hatten); der DSP56K/Symphony Audio DSPs von Freescale (nachdem sie von Motorola ausgegliedert wurden).
– David Cary
6. Juli 2012 um 13:52 Uhr
@msemack C64xx hat Hardware für 8/16/32/40 und 8-Bit-Zeichen
– Benutzer3528438
16. April 2015 um 20:45 Uhr
Eher, als assert() (wenn du das meinst), würde ich verwenden #if CHAR_BIT != 8 … #error "I require CHAR_BIT == 8" … #endif
– Keith Thompson
2. Oktober 2015 um 20:52 Uhr
@KeithThompson Gibt es einen Grund, es nicht zu verwenden? static_assert()?
– Qix – MONICA WURDE MISSHANDELT
17. Februar 2017 um 4:35 Uhr
Johannes Feminella
Wenn Sie Code schreiben und über plattformübergreifende Unterstützung nachdenken (z. B. für allgemein verwendbare Bibliotheken), welche Art von Überlegung lohnt es sich, Plattformen mit Nicht-8-Bit-Zeichen zu widmen?
Es ist nicht so sehr, dass es sich lohnt, über etwas nachzudenken, als dass es sich an die Regeln hält. In C++ zum Beispiel sagt der Standard, dass alle Bytes “mindestens” 8 Bit haben werden. Wenn Ihr Code davon ausgeht, dass Bytes genau 8 Bits haben, verstoßen Sie gegen den Standard.
Das mag jetzt albern erscheinen –“selbstverständlich Alle Bytes haben 8 Bit!“, höre ich Sie sagen. Aber viele sehr schlaue Leute haben sich auf Annahmen verlassen, die keine Garantien waren, und dann ist alles kaputt gegangen. Die Geschichte ist voll von solchen Beispielen.
Beispielsweise gingen die meisten Entwickler Anfang der 90er Jahre davon aus, dass eine bestimmte No-Op-CPU-Timing-Verzögerung mit einer festen Anzahl von Zyklen eine feste Taktzeit in Anspruch nehmen würde, da die meisten Consumer-CPUs ungefähr die gleiche Leistung hatten. Leider wurden Computer sehr schnell schneller. Dies brachte den Aufstieg von Boxen mit „Turbo“-Knöpfen hervor – deren Zweck ironischerweise darin bestand, den Computer zu verlangsamen, damit Spiele mit der Zeitverzögerungstechnik mit angemessener Geschwindigkeit gespielt werden konnten.
Ein Kommentator fragte, wo im Standard steht, dass char mindestens 8 Bit haben muss. Es ist in Abschnitt 5.2.4.2.1. Dieser Abschnitt definiert CHAR_BITdie Anzahl der Bits in der kleinsten adressierbaren Entität, und hat einen Standardwert von 8. Es sagt auch:
Ihre implementierungsdefinierten Werte müssen in der Größenordnung (absoluter Wert) gleich oder größer als die gezeigten sein, mit demselben Vorzeichen.
Daher eignet sich jede Zahl gleich 8 oder höher für die Substitution durch eine Implementierung in CHAR_BIT.
Ich habe seit mindestens 20 Jahren keinen Turbo-Knopf mehr gesehen – denkst du wirklich, dass er für die Frage relevant ist?
– Markieren Sie Lösegeld
20. Januar 2010 um 3:30 Uhr
@Mark Ransom: Das ist der springende Punkt. Entwickler verlassen sich oft auf Annahmen, die im Moment wahr erscheinen, aber viel wackeliger sind, als es zunächst den Anschein hat. (Ich kann nicht zählen, wie oft ich es gemacht habe das Fehler!) Der Turbo-Button sollte eine schmerzhafte Mahnung sein, keine unnötigen Annahmen zu treffen und schon gar keine Annahmen zu machen, die nicht durch einen Sprachstandard garantiert sind, als wären sie unveränderliche Tatsachen.
– Johannes Feminella
20. Januar 2010 um 3:33 Uhr
Könnten Sie auf eine Stelle im C++-Standard hinweisen, die besagt, dass das Tschüss mindestens 8 Bits hat? Es ist ein allgemeiner Glaube, aber ich persönlich habe es nicht im Standard gefunden. Das einzige, was ich in Standard gefunden habe, ist, durch welche Zeichen darstellbar sein müssen char Es gibt mehr als 64 davon, aber weniger als 128, also würden 7 Bit ausreichen.
– Adam Badura
20. Januar 2010 um 6:48 Uhr
Abschnitt 18.2.2 ruft dafür den C-Standard auf. Im C-Standard ist es Abschnitt 7.10 und dann Abschnitt 5.4.2.4.1. Seite 22 in der C-Norm.
– Windows-Programmierer
21. Januar 2010 um 3:48 Uhr
Daher erwähnen andere Antworten und Kommentare Maschinen mit 5-Bit-, 6-Bit- und 7-Bit-Bytes. Bedeutet das, dass Sie auf dieser Maschine kein C-Programm ausführen können, das dem Standard entspricht?
Auch Honeywell-Maschinen, wie vielleicht die zweite Maschine, auf der C implementiert wurde. Siehe K&R-Version 1.
– Windows-Programmierer
20. Januar 2010 um 3:44 Uhr
Tatsächlich hatte der Dec-10 auch 6-Bit-Zeichen – Sie könnten 6 davon in ein 36-Bit-Wort packen (Ex-Dec-10-Programmierer spricht)
– anon
20. Januar 2010 um 14:52 Uhr
Der DEC-20 verwendete fünf 7-Bit-ASCII-Zeichen pro 36-Bit-Wort auf dem TOPS-20-Betriebssystem.
– David R. Tribble
20. Januar 2010 um 17:19 Uhr
Dieser Witz wurde tatsächlich implementiert, um Unicode auf dieser Architektur zu unterstützen.
– Josua
14. Dezember 2011 um 7:31 Uhr
Ich nehme an, dass der Grund, warum Oktal tatsächlich jemals verwendet wurde, darin bestand, dass 3 Oktalziffern ein 9-Bit-Byte sauber darstellen, genau wie wir heute normalerweise Hexadezimal verwenden, weil zwei Hexadezimalziffern ein 8-Bit-Byte sauber darstellen.
– Namen53
11. Juli 2012 um 0:20 Uhr
Ein paar sind mir bekannt:
DEC PDP-10: variabel, aber meistens 7-Bit-Zeichen, 5 pro 36-Bit-Wort gepackt, oder 9-Bit-Zeichen, 4 pro Wort
Windows CE: unterstützt den char-Typ einfach überhaupt nicht – erfordert stattdessen 16-Bit-wchar_t
Es gibt keinen vollständig portablen Code. 🙂
Ja, es kann verschiedene Byte-/Zeichengrößen geben. Ja, es kann C/C++-Implementierungen für Plattformen mit sehr ungewöhnlichen Werten von geben CHAR_BIT und UCHAR_MAX. Ja, manchmal ist es möglich, Code zu schreiben, der nicht von der Zeichengröße abhängt.
Fast jeder echte Code ist jedoch nicht eigenständig. ZB könnten Sie einen Code schreiben, der binäre Nachrichten an das Netzwerk sendet (das Protokoll ist nicht wichtig). Sie können Strukturen definieren, die erforderliche Felder enthalten. Dann müssen Sie es serialisieren. Nur das binäre Kopieren einer Struktur in einen Ausgabepuffer ist nicht portierbar: Im Allgemeinen kennen Sie weder die Byte-Reihenfolge für die Plattform noch die Ausrichtung der Strukturmitglieder, sodass die Struktur nur die Daten enthält, aber nicht beschreibt, wie die Daten serialisiert werden sollen .
OK. Sie können Byte-Order-Transformationen durchführen und die Strukturmitglieder verschieben (z uint32_t o.ä.) verwenden memcpy in den Puffer. Warum memcpy? Denn es gibt viele Plattformen, auf denen es nicht möglich ist, 32-Bit (16-Bit, 64-Bit — kein Unterschied) zu schreiben, wenn die Zieladresse nicht richtig ausgerichtet ist.
Sie haben also bereits viel getan, um Portabilität zu erreichen.
Und jetzt die letzte Frage. Wir haben einen Puffer. Die Daten davon werden an das TCP/IP-Netzwerk gesendet. Ein solches Netzwerk nimmt 8-Bit-Bytes an. Die Frage ist: von welcher Art sollte der Puffer sein? Wenn Ihre Zeichen 9-Bit sind? Wenn sie 16-Bit sind? 24? Vielleicht entspricht jedes Zeichen einem 8-Bit-Byte, das an das Netzwerk gesendet wird, und es werden nur 8 Bits verwendet? Oder werden vielleicht mehrere Netzwerkbytes in 24/16/9-Bit-Zeichen gepackt? Das ist eine Frage, und es ist schwer zu glauben, dass es eine einzige Antwort gibt, die auf alle Fälle zutrifft. Viele Dinge hängen von der Socket-Implementierung für die Zielplattform ab.
Also, wovon ich spreche. Normalerweise kann Code relativ einfach erstellt werden bis zu einem gewissen Grad tragbar. Dies ist sehr wichtig, wenn Sie den Code auf verschiedenen Plattformen verwenden möchten. Aber, Die Verbesserung der Portabilität über dieses Maß hinaus ist eine Sache, die viel Aufwand erfordert und oft wenig bringt, da der echte Code fast immer von anderem Code abhängt (Socket-Implementierung im obigen Beispiel). Ich bin sicher, dass für etwa 90% des Codes die Fähigkeit, auf Plattformen mit anderen Bytes als 8-Bit zu arbeiten, fast nutzlos ist, da er eine Umgebung verwendet, die an 8-Bit gebunden ist. Überprüfen Sie einfach die Bytegröße und führen Sie die Bestätigung der Kompilierungszeit durch. Für eine höchst ungewöhnliche Plattform müssen Sie mit ziemlicher Sicherheit viel umschreiben.
Aber wenn Ihr Code sehr „eigenständig“ ist – warum nicht? Sie können es so schreiben, dass unterschiedliche Bytegrößen zulässig sind.
Speichert man ein Oktett pro unsigned char value sollte es keine Portabilitätsprobleme geben, es sei denn, der Code verwendet Aliasing-Tricks anstelle von Verschiebungen, um Sequenzen von Oktetten in/von größeren Integer-Typen zu konvertieren. Persönlich denke ich, dass der C-Standard Intrinsics definieren sollte, um Ganzzahlen aus Sequenzen kürzerer Typen zu packen/entpacken (am typischsten char) Speichern einer festen garantiert verfügbaren Anzahl von Bits pro Element (8 pro unsigned char16 pro unsigned shortoder 32 pro unsigned long).
– Superkatze
25. Juli 2015 um 19:42 Uhr
dmckee — Ex-Moderator-Kätzchen
Es scheint, dass Sie es immer noch können Kauf dir einen IM6100 (dh ein PDP-8 auf einem Chip) aus einem Lagerhaus. Das ist eine 12-Bit-Architektur.
Speichert man ein Oktett pro unsigned char value sollte es keine Portabilitätsprobleme geben, es sei denn, der Code verwendet Aliasing-Tricks anstelle von Verschiebungen, um Sequenzen von Oktetten in/von größeren Integer-Typen zu konvertieren. Persönlich denke ich, dass der C-Standard Intrinsics definieren sollte, um Ganzzahlen aus Sequenzen kürzerer Typen zu packen/entpacken (am typischsten char) Speichern einer festen garantiert verfügbaren Anzahl von Bits pro Element (8 pro unsigned char16 pro unsigned shortoder 32 pro unsigned long).
– Superkatze
25. Juli 2015 um 19:42 Uhr
Alok Singhal
Viele DSP-Chips haben 16- oder 32-Bit char. TI stellt routinemäßig solche Chips her zum Beispiel.
9981400cookie-checkWelche Plattformen haben etwas anderes als 8-Bit-Zeichen?yes
Die CDC Cyber-Serie hatte eine 6/12-Bit-Codierung. Die beliebtesten Zeichen waren 6 Bit. Die restlichen Zeichen verwendeten 12 Bit.
– Thomas Matthäus
20. Januar 2010 um 0:07 Uhr
Der PDP-11 hat es auf den Punkt gebracht. Die Vorstellung, dass ein Zeichen in einem Zeichen kodiert werden kann, ist ernsthaft veraltet.
– Hans Passant
20. Januar 2010 um 1:38 Uhr
“Der PDP-11 hat es geschafft” – Sie meinen, weil C zuerst für den PDP-11 mit 8-Bit-Bytes implementiert wurde? Aber C wurde als nächstes für Honeywell-Maschinen mit 9-Bit-Bytes implementiert. Siehe K&R Version 1. Außerdem wurde die Frage nach char (dh byte) und nicht nach character gestellt (ein oder mehrere Bytes codieren etwas, nach dem nicht gefragt wurde).
– Windows-Programmierer
20. Januar 2010 um 3:40 Uhr
DEC-10 und DEC-20 hatten 36-Bit-Wörter. Fünf 7-Bit-ASCII-Zeichen pro Wort waren durchaus üblich. Außerdem wurden sechs 6-Bit-Zeichen verwendet.
– David R. Tribble
20. Januar 2010 um 17:12 Uhr
@CraigMcQueen: Wenn ich mich richtig erinnere, lässt CodeVision für Atmel-Mikrocontroller die Größe von char wählen
– vsz
20. Februar 2016 um 10:10 Uhr