2012-09-30 24 views
13

In this answer und die beigefügten Bemerkungen machen Pavel Minaev das folgende Argument, dass in C, um die einzigen Typen, die uint8_t typedef'd char und unsigned char sind werden kann. Ich sehe this draft des C-Standards.Kann uint8_t ein Nicht-Zeichen-Typ sein?

  • Die Anwesenheit von uint8_t impliziert das Vorhandensein eines entsprechenden Typs int8_t (7.18.1p1).
  • int8_t ist 8 Bit breit und hat keine Padding-Bits (7.18.1.1p1).
  • Entsprechende Typen haben die gleiche Breite (6.2.5p6), also uint8_t ist auch 8 Bit breit.
  • unsigned char ist CHAR_BIT Bits breit (5.2.4.2.1p2 und 6.2.6.1p3).
  • CHAR_BIT ist mindestens 8 (5.2.4.2.1p1).
  • CHAR_BIT ist höchstens 8, weil entweder uint8_tunsigned char ist, oder es ist eine nicht-unsigned char, nicht-Bit-Halbbild-Typ, dessen Breite ein Vielfaches von CHAR_BIT (6.2.6.1p4).

auf dieses Argument stimme ich, dass, wenn uint8_t vorhanden ist, dann sowohl sie als auch unsigned char identische Darstellungen haben: 8 Wert Bits und 0 Füllbits. Dies scheint sie nicht zu zwingen, vom gleichen Typ zu sein (z. B. 6.2.5p14).

Ist es erlaubt, dass uint8_t in eine ausgefahrene unsigned integer Typ typedef'd wird (6.2.5p6) mit der gleichen Darstellung wie unsigned char? Sicherlich muss es typedef'd (7.18.1.1p2) sein, und es kann kein anderer vorzeichenloser Integer-Typ sein als unsigned char (oder char, wenn es unsigniert ist). Dieser hypothetische erweiterte Typ wäre kein Zeichentyp (6.2.5p15) und würde daher keinen Alias-Zugriff auf ein Objekt eines inkompatiblen Typs (6.5p7) zulassen, was für mich der Grund ist, warum ein Compiler-Schreiber dies tun möchte Ding.

+0

keine Antwort auf Ihre ausdrückliche Frage verwendet, aber es ist möglich, dass 'char 'ist ein vorzeichenloser Typ, dann könnte' uint8_t' in 'char' anstelle von' u typedef'ed sein nsigned char'. –

+0

An einem Punkt (vor einigen Jahren) gab es im GCC-Projekt eine ernsthafte Diskussion über das Hinzufügen eines erweiterten Integertyps mit exakt den Eigenschaften, die Sie beschreiben - acht Bit breit, kein Zeichentyp und kein Sonderfall im Typ Alias-Analyse - aber soweit ich weiß, ging es nie irgendwo hin, und es gab keinen Hinweis darauf, dass es der zugrunde liegende Typ für "uint8_t" war (möglicherweise nur weil niemand zu der Zeit daran dachte). – zwol

+0

Beachten Sie, dass 'uint8_t' überhaupt nicht existieren muss. Es ist nur bedingt definiert. –

Antwort

-1

int8_t und uint8_t unterscheiden sich nur durch REPRÄSENTATION und NICHT den Inhalt (Bits). int8_t verwendet untere 7 Bits für Daten und das 8. Bit soll "Vorzeichen" (positiv oder negativ) darstellen. Daher ist der Bereich von int8_t von -128 bis +127 (0 wird als positiver Wert betrachtet).

uint8_t ist ebenfalls 8 Bit breit, ABER die darin enthaltenen Daten sind IMMER positiv. Daher ist der Bereich von uint8_t von 0 bis 255.

In Anbetracht dieser Tatsache ist char 8 Bits breit. unsigned char wäre auch 8 Bits breit, aber ohne das "Zeichen". Ähnlich kurz und vorzeichenlos kurz sind beide 16 Bits breit.

Wenn jedoch "unsigned int" 8 Bit breit ist, dann .. da C nicht zu Typ-Nazi ist, ist es erlaubt. Und warum würde ein Compiler-Schreiber so etwas zulassen? Lesbarkeit

+1

Die Breite von "unsigned int" ist nicht weniger als 16. – user1710520

+0

gemäß den Spezifikationen YES. Aber wir sehen das hypothetisch, nicht wahr? –

+1

Hypothetisch, aber normkonform. –

4

Wenn uint8_t vorhanden ist, die nicht-padding Anforderung bedeutet, dass CHAR_BIT 8. Allerdings ist, gibt es keinen fundamentalen Grund, warum ich finden kann, warum uint8_t nicht mit einem erweiterten Integer-Typ definiert werden könnte. Außerdem gibt es keine Garantie, dass die Darstellungen identisch sind. Zum Beispiel könnten die Bits in umgekehrter Reihenfolge interpretiert werden.

Während dies albern und grundlos ungewöhnlich für uint8_t scheint, könnte es viel Sinn für int8_t machen. Wenn eine Maschine nativ Einerkomplement oder Vorzeichen/Betrag verwendet, ist signed char nicht für int8_t geeignet. Es könnte jedoch einen erweiterten vorzeichenbehafteten Integer-Typ verwenden, der zwei Komplemente emuliert, um int8_t bereitzustellen.

+0

"zum Beispiel könnten die Bits in umgekehrter Reihenfolge interpretiert werden". Bedeutet das, dass die Bits in umgekehrter Reihenfolge in "unsigned char" vs (jedes einzelne Byte von) "unsigned int" interpretiert werden können? Oder sind es nur erweiterte Integer-Typen, die den Datenbus verdrahten können ;-) –

+0

@SteveJessop: 'unsigned int' ist typischerweise N Bytes (wobei N typischerweise 4 ist) entweder in Little Endian oder Big Endian Reihenfolge interpretiert, aber der Standard sagt nichts über die Reihenfolge der Bytes oder sogar der Bits. Ich bin mir nicht sicher, ob Ihre Frage "Querverkabelung des Datenbusses" ernst ist, aber es gibt keinen Grund, dass "* (unsigned char *) & (uint8_t) {1}" 1 sein muss und nicht irgendeine andere Potenz von Zwei . (Die "reine binäre" Anforderung bedeutet jedoch, dass es * eine * Potenz von zwei ist.) –

+1

Ich meinte nicht ernsthaft, dass es durch eine physische Querverdrahtung des Busses erreicht werden würde, aber abgesehen davon war die Frage ernst. Es ist nur, ich glaube nicht, dass ich jemals zuvor darüber nachgedacht habe 'unsigned int a = 1; für (unsigned char * p = (vorzeichenloses char *) & a; p <(vorzeichenloses char *) (&a+1); ++ p) if (* p == 1) zurück; 'muss nicht zurückkehren. Ebenso denke ich etwas albern wie' unsigned int a = 0xF; strlen ((char *) &a); 'ist ein potentieller Pufferüberlauf, vorausgesetzt 'sizeof (a)> = 4' (4 ist die Anzahl der im Wert gesetzten Bits), außer der Standard sagt, dass die Bytes von Das Objekt Repr. sind * zusammenhängende * Wert Bits –

2

In 6.3.1.1 (1) (des N1570 Entwurf des C11-Standard), können wir

den Rang eines Standard-Integer-Typ ist größer als der Rang eines erweiterten Integer-Typ lesen mit die gleiche Breite.

So erlaubt der Standard explizit das Vorhandensein von erweiterten Integer-Typen der gleichen Breite wie ein Standard-Integer-Typ.

Es gibt nichts in der Norm ist das Verbot einer

typedef implementation_defined_extended_8_bit-unsigned_integer_type uint8_t; 

wenn die erweiterte Integer-Typ, die Spezifikationen für uint8_t (keine Füllbits, einer Breite von 8 Bits) entspricht, so weit wie ich sehen kann.

Also ja, wenn die Implementierung stellt eine solche erweiterte Integer-Typ, uint8_tkann zu, dass sein typedef.

0

uint8_t möglicherweise vorhanden sein und eine unterschiedliche Art von unsigned char sein.

Eine signifikante Auswirkung davon ist in der Überladungsauflösung; es ist plattformabhängig, ob:

uint8_t by = 0; 
std::cout << by; 

  1. operator<<(ostream, char)
  2. operator<<(ostream, unsigned char) oder
  3. operator<<(ostream, int)
+0

Dies ist eine C Frage.Sie müssten C++ Referenzen für alle Sachen, die OP zitiert, um Ihre Forderung zu sichern –

+0

Meinst du zu sagen "' uint8_t "kann existieren und ein unterschiedlicher Typ sein, sowohl von' char' als auch von 'unsigned char'" oder behauptet man nur, dass es sich von 'unsigned char' unterscheiden könnte es ist "char"? Auch, warum bekomme ich deja vu dies zu schreiben –