2016-08-08 38 views
13

Was eigentlich gehört zum "Zeichentyp" in C11 - neben char natürlich?Was zählt in C11 als Zeichentyp?

Genauer gesagt, die besonderen Ausnahmen für den Zeichentyp sein (zum Beispiel, dass jedes Objekt kann durch eine L-Wert-Expression von Zeichentyp zugegriffen werden - § 6.5/7 in C11-Standard sehen), auf die Betontypen tun sie bewerben sich? Sie scheinen gelten für uint8_t und int8_t von stdint.h, aber ist das garantiert? Auf der anderen Seite betrachtet gcc char16_t nicht von uchar.h als "Zeichentyp".

+0

Auch 'signed char' und' unsigned char'. –

+0

Beachten Sie, dass 'int8_t' und' uint8_t' nur Aliase für vorhandene Typen sind. –

+0

Es gab ernsthafte Vorschläge, um 'int8_t' und' uint8_t' auf erweiterten Integer-Typen aufzubauen, funktional identisch mit 'signed char' und' unsigned char' bzw. _except_, die sie nicht als "character types" für §6.5/7 zählen würden. Soweit ich weiß, hat keine Umsetzung diese Idee durchgesetzt, aber mir ist auch kein Grund bekannt, dass es verboten ist.(Der Vorteil wäre zum Beispiel, dass Sie jetzt String-Zeiger haben könnten, die _ididn_ nicht alle anderen Pointer im Programm aliasieren.) – zwol

Antwort

8

Nur char, signed char und unsigned char .

Die Typen uint8_t, int8_t, char16_t oder jede Art in Form intN_t oder charN_t, sein können oder auch nicht Synonyme für einen Zeichentyp.


(Zitiert aus: ISO/IEC 9899: 201x 6.2.5 Typen 15)
Die drei Typen verkohlen, signed char und unsigned char werden kollektiv die Zeichentypen bezeichnet.

+0

Wenn 'sizeof (char) == sizeof (int8_t)' dann ist 'int8_t' * * ein Zeichentyp? –

+0

@ wolf-revo-cats Nein, das ist nicht garantiert. Es könnte theoretisch typedefed als ein erweiterter Integer-Typ sein. – 2501

+1

@ 2501 Die 'intN_t'-Typen sind optional und können nicht auf einer Maschine existieren, die keinen genau 'N'-Bit-Typ hat. Und da "char" -Typen die kleinste adressierbare Einheit auf einer Maschine sein müssen und mindestens 8 Bit lang sein müssen ... wenn eine Maschine die 'int8_t'-Typen unterstützt, müssen sie Aliase für '[[un] signed] char sein '. Oder habe ich irgendwo eine logische Lücke übersehen? Ich denke, einige exotische Maschinen könnten Typen mit der gleichen Breite, aber unterschiedlichen Zeichen oder Bitdarstellungen anbieten, wodurch sie besser für das eine oder andere von 'char' oder' intN_t' geeignet sind. –

7

char, signed char und unsigned char sind die Zeichentypen in C11. Dies ist seit C89 dasselbe.

Behandeln int8_t (oder uint8_t) als Zeichentyp hat viele Probleme.

  1. Sie sind optional.
  2. Sie können nicht existieren, wenn CHAR_BIT > 8.
  3. Definiert zu arbeiten, wenn die Implementierung 2's Komplement Darstellung (die am häufigsten ist) verwendet. Aber sie sind andere Darstellungen, nämlich 1s Komplement und Vorzeichen-Magnitude definiert/erlaubt durch den C-Standard.

Da sind sie, wenn sie vorhanden ist, typedef zu einem bestehenden Typ, können Sie wahrscheinlich mit der Verwendung von int8_t oder uint8_t als Zeichentyp in der Praxis wegkommen. Aber der Standard garantiert nichts und es gibt keinen Grund, sie als solche überhaupt zu behandeln, wenn Sie die echten Zeichentypen haben.

+1

I zuvor verwendet die 'cstdint'-typedefs hielt aber an und ging zurück zu guten alten' char's für genau die Gründe, die du gabst. Es macht einfach Sinn, sagt die Absicht entsprechend den speziellen Zuwendungen, die man den "Char's" gewährt, und schützt später vor potentiellen Unfällen (bei einer exotischen Implementierung). –

+0

Ich möchte fragen, ob es tatsächlich eine Implementierung gibt, wo 'char' größer als ein Byte ist? Wenn Sie beispielsweise GNU libc's memset in den Zeilen 'cccc = (unsigned char) c; cccc | = cccc << 8; cccc | = cccc << 16; 'dies * würde * brechen, wenn' char' größer als ein Byte ist. Mit GNU scheint also implizit garantiert zu sein, dass 'char' ein Byte groß ist. –

+1

Siehe: [Welche Plattformen haben etwas anderes als 8-Bit-Zeichen?] (Http://stackoverflow.com/questions/2098149/what-platforms-have-etwas-ande-8-bit-char) für einige Beispiele . Ja, das würde glibc brechen. Aber glibc verwendet typischerweise arch-spezifischen Assembler-Code für memset, memcpy usw. Also ist dieser Code möglicherweise nicht der * tatsächlich * verwendete. Außerdem gilt CHAR_BIT! = 8 für DSPs. Aber Sie können vernünftigerweise annehmen, dass CHAR_BIT = 8 auf den meisten Desktop-Systemen ist und POSIX erfordert, dass CHAR_BIT genau 8 Bits beträgt. Aber der Standard deckt auch viele andere Systeme ab. –