Forum: Compiler & IDEs unsigned char vs. uint_8


von Maddel ihm sein Kumpel (Gast)


Lesenswert?

Hallo bitte verzeiht meine Frage, aber ich bim mit C noch ganz am 
Anfang. In meinem C-Buch ist nur von unsigned bzw. signed char  die 
Rede, aber hier im Forum schreibt man dafür "uint_8" usw.
Woher kennt der Compiler uint_8 ?
Btw. gibt es auch uint_64 oder gar uint_128 ?

von (prx) A. K. (prx)


Lesenswert?

Maddel ihm sein Kumpel schrieb:
> Woher kennt der Compiler uint_8 ?

Überhaupt nicht. Er kennt ggf. uint8_t.

Siehe stdint.h

von Rolf Magnus (Gast)


Lesenswert?

Maddel ihm sein Kumpel schrieb:
> Hallo bitte verzeiht meine Frage, aber ich bim mit C noch ganz am
> Anfang. In meinem C-Buch ist nur von unsigned bzw. signed char  die
> Rede,

Evtl. ist dein Buch dann etwas veraltet. Die typedefs aus stdint.h sind 
seit 1999 offizieller Bestandteil von C.

von A. H. (ah8)


Lesenswert?

Maddel ihm sein Kumpel schrieb:
> In meinem C-Buch ist nur von unsigned bzw. signed char  die
> Rede, aber hier im Forum schreibt man dafür "uint_8" usw.

uint8_t ist ein unsigned integer Type mit exakt 8 Bit Breite. char 
ist ein Datentyp (implementationsabhängig signed oder unsigned) mit 
mindestens 8 Bit Breite, aber groß genug um ein Zeichen des 
systemspezifischen Character-Sets aufzunehmen. Ich habe zwar noch keinen 
Compiler gesehen, wo dass so ist, theoretisch könnten das aber auch mehr 
als 8 Bit sein. Da die meisten Compiler auf einem 8-Bit Character-Sets 
basieren ist uint8_t in der Regel nur ein Alias auf unsigned char, 
definiert in <stdint.h>. Das muss aber nicht so sein. (Das alls sagt 
zumindest mein C++ Standard. Ich unterstelle mal, dass das in C genauso 
ist.)

von Rolf Magnus (Gast)


Lesenswert?

A. H. schrieb:
> Da die meisten Compiler auf einem 8-Bit Character-Sets
> basieren ist uint8_t in der Regel nur ein Alias auf unsigned char,
> definiert in <stdint.h>. Das muss aber nicht so sein.

Naja, viele andere Möglichkeiten gibt es nicht, denn kleiner als char 
kann uint8_t nicht sein, und größer kann er auch nicht sein.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Es gibt/gab ein paar DSPs (bspw. TMS320Cxx und MC56000), die keine
8-Bit-Bytes adressieren können. Bei denen hat dann ein char die
Wortbreite des Prozessors (bspw. 24 oder 32 Bit). Ein uint8_t gibt
es auf solchen Prozessoren nicht.

von Stefan R. (srand)


Lesenswert?

Rolf Magnus schrieb:
> denn kleiner als char
> kann uint8_t nicht sein, und größer kann er auch nicht sein.

Warum glaubst du das?

von Rolf Magnus (Gast)


Lesenswert?

Stefan Rand schrieb:
> Rolf Magnus schrieb:
>> denn kleiner als char kann uint8_t nicht sein, und größer kann er auch
>> nicht sein.
>
> Warum glaubst du das?

Ich weiß es, weil die logische Konsequenz aus den Regeln von ISO C 
ist. char ist der kleinstmögliche Typ (sizeof(char) ist per Definition 
1). Also kann uint8_t nicht kleiner sein.
Und größer als char kann uint8_t natürlich auch nicht sein, denn char 
ist ja mindestens 8 Bit groß, also so groß wie uint8_t.

von (prx) A. K. (prx)


Lesenswert?

Stefan Rand schrieb:
>> denn kleiner als char kann uint8_t nicht sein
>
> Warum glaubst du das?

Weil man bei uint8_t < char in arge Bedrängnis gerät.

Da char auch für ein sogenanntes Byte und die kleinste adressierbare 
Einheit steht, zumindest aus Sicht von C, wäre ein uint8_t kleiner als 
char nicht mehr adressierbar.

Es wäre aber als bizarres Zugeständnis an jene Programmierer denkbar, 
die bei 9 Bit Bytes trotzdem jenseits 255 einen Überlauf erwarten. 
uint8_t würde dann 8 Bits im 9 Bit Byte speichern, mit künstlichem 
Überlauf wie bei 8 Bit Daten.

: Bearbeitet durch User
von A. H. (ah8)


Lesenswert?

> Ich weiß es, weil die logische Konsequenz aus den Regeln von ISO C
> ist. char ist der kleinstmögliche Typ (sizeof(char) ist per Definition
> 1). Also kann uint8_t nicht kleiner sein.
> Und größer als char kann uint8_t natürlich auch nicht sein, denn char
> ist ja mindestens 8 Bit groß, also so groß wie uint8_t.

http://www.unix.com/man-page/posix/7posix/stdint.h/:
1
 Note:  The "width" of an integer type is the number of bits used to store its value  in        a
2
              pure  binary  system;  the  actual type may use more bits than that (for example, a
3
              28-bit type could be stored in 32 bits of actual storage). An N-bit signed type has
4
              values  in  the range -2**N-1 or 1-2**N-1 to 2**N-1-1, while an N-bit unsigned type
5
              has values in the range 0 to 2**N-1.
Es geht hier um die Anzahl der Bits, die verwendet werden, um den 
Wertebereich eines Typs darzustellen, nicht um die Anzahl der Bits, die 
verwendet werden, um einen Wert dieses Typs zu speichern.

von A. H. (ah8)


Lesenswert?

A. K. schrieb:
> Es wäre aber als bizarres Zugeständnis an jene Programmierer denkbar,
> die bei 9 Bit Bytes trotzdem jenseits 255 einen Überlauf erwarten.
> uint8_t würde dann 8 Bits im 9 Bit Byte speichern, mit künstlichem
> Überlauf wie bei 8 Bit Daten.

Genau das sagt meiner Ansicht nach der Standard aus. Für uint8_t – 
wenn er denn existiert – sollte gelten 0xff+0x01 == 0x00. Für char ist 
das nicht garantiert.

von Stefan R. (srand)


Lesenswert?

Rolf Magnus schrieb:
> Stefan Rand schrieb:
>> Rolf Magnus schrieb:
>>> denn kleiner als char kann uint8_t nicht sein, und größer kann er auch
>>> nicht sein.
>>
>> Warum glaubst du das?
>
> Ich weiß es, weil die logische Konsequenz aus den Regeln von ISO C
> ist. char ist der kleinstmögliche Typ (sizeof(char) ist per Definition
> 1). Also kann uint8_t nicht kleiner sein.
> Und größer als char kann uint8_t natürlich auch nicht sein, denn char
> ist ja mindestens 8 Bit groß, also so groß wie uint8_t.

Naja, nur wenn uint8_t existiert, aber klar, da habe ich mich blöd 
ausgedrückt.

Ich meinte den Fall, daß char größer acht Bit ist, womit uint8_t 
schlecht ein typedef auf unsigned char sein kann.

Aber das ist halt eine Aussage über eine nicht existierende Entität, und 
insofern wirklich unspannend.

von Rolf Magnus (Gast)


Lesenswert?

A. H. schrieb:
> Es geht hier um die Anzahl der Bits, die verwendet werden, um den
> Wertebereich eines Typs darzustellen, nicht um die Anzahl der Bits, die
> verwendet werden, um einen Wert dieses Typs zu speichern.

Das würde aber immer noch bedeuten, daß uin8t_t zwar nicht alle Bits 
nutzen, aber trotzdem mindestens so viele wie char haben muß. Das ist 
allerdings POSIX und nicht ISO C. In C99 steht die von dir zitierte 
"Note" nicht.

Was mich jetzt, nachdem ich mal in C99 mal ein bischen nachgelesen habe, 
wundert, ist die Unterscheidung zwischen signed und unsigned (Das 
gleiche steht auch in deiner verlinkten Man-Page). Bei signed heißt es 
da:

******************************
The typedef name intN_t designates a signed integer type with width N , 
no padding bits, and a two’s complement representation. Thus, int8_t 
denotes a
signed integer type with a width of exactly 8 bits.
******************************

"No padding bits" heißt, daß alle Bits genutzt werden müssen. Bei 
unsigned fehlt dieser Teil jedoch:

******************************
The typedef name uintN_t designates an unsigned integer type with width 
N. Thus, uint24_t denotes an unsigned integer type with a width of 
exactly 24 bits.
******************************

Das würde ja heißen, daß uint8_t auch 12 Bit groß sein und dann nur 8 
bits benutzen dürfte, int8_t dagegen alle 12 Bits nutzen müßte. Ich bin 
verwirrt...

von Rolf Magnus (Gast)


Lesenswert?

Ok, kurz nach dem Posten noch den Logikfehler entdeckt. int8_t dürfte ja 
nicht 12 Bits nutzen, sondern eben nur 8. Das würde dann aber bedeuten, 
daß es im Speicher auch immer exakt 8 Bit belegen muß, wodurch dann in 
der Konsequenz das gleiche für uint8_t gelten würde.

von (prx) A. K. (prx)


Lesenswert?

Rolf Magnus schrieb:
> In C99 steht die von dir zitierte "Note" nicht.

Kann sie auch nicht. POSIX ist nur mit Zweierkomplementdarstellung 
verträglich. C ist demgegenüber neutral, erlaubt z.B. auch das 
Einerkomplement.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Rolf Magnus schrieb:
> "No padding bits" heißt, daß alle Bits genutzt werden müssen. Bei
> unsigned fehlt dieser Teil jedoch:

In C11 nicht mehr.

von Rolf Magnus (Gast)


Lesenswert?

A. K. schrieb:
> Rolf Magnus schrieb:
>> In C99 steht die von dir zitierte "Note" nicht.
>
> Kann sie auch nicht. POSIX ist nur mit Zweierkomplementdarstellung
> verträglich. C ist demgegenüber neutral, erlaubt z.B. auch das
> Einerkomplement.

Das Zitat von oben ist aus C99, wo für intN_t explizit eine

> two’s complement representation

gefordert ist. Hat sich das in C11 auch geändert? Ich hab leider nur C99 
zur Verfügung.

A. K. schrieb:
> Rolf Magnus schrieb:
>> "No padding bits" heißt, daß alle Bits genutzt werden müssen. Bei
>> unsigned fehlt dieser Teil jedoch:
>
> In C11 nicht mehr.

Ok, dann war es, wie ich mir schon dachte, nur ein Fehler in C99.

von Maddel ihm sein Kumpel (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Evtl. ist dein Buch dann etwas veraltet. Die typedefs aus stdint.h sind
> seit 1999 offizieller Bestandteil von C.

Oh ja ist von 1989.
Also soll man anstelle von z.B.
signed long long int besser int64_t schreiben.
Ist ja kürzer und schneller zu schreiben.
Oder gibt es sonst noch Vor oder Nachteile?!

von Rolf Magnus (Gast)


Lesenswert?

Maddel ihm sein Kumpel schrieb:
> Also soll man anstelle von z.B.
> signed long long int besser int64_t schreiben.
> Ist ja kürzer und schneller zu schreiben.
> Oder gibt es sonst noch Vor oder Nachteile?!

int64_t ist ein Typ, der exakt 64 Bit breit ist. Den solltest du dann 
verwenden, wenn du an der Stelle darauf angewiesen bist, daß es wirklich 
genau 64 Bit sind.

von (prx) A. K. (prx)


Lesenswert?

Rolf Magnus schrieb:
> gefordert ist. Hat sich das in C11 auch geändert? Ich hab leider nur C99
> zur Verfügung.

Ich lag oben falsch, POSIX drückt sich letztlich nur anders aus. Die 
Sprache an sich ist neutral, bestimmte Definitionen bezüglich der 
Umgebung, wie die zu uintN_t, sind es aber auch im Standard nicht.

C11 draft n1570: 
http://www.compsci.hunter.cuny.edu/~sweiss/resources/c11standard.pdf

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.