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 ?
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.
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.)
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.
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.
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.
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.
> 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.
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.
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.
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...
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.
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.
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.
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?!
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.
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