Das ist jetzt nicht wirklich neu. Das Ding ist doch hier schon vor
Ewigkeiten verrissen worden.
"5.2 Der Datentyp ᅵintᅵ (Integer)
Der Datentyp int muss, gemᅵᅵ ANSI C, mindestens eine Grᅵᅵe von zwei Byte
aufweisen. Mit diesen zwei Bytes lᅵsst sich ein Zahlenraum von -32768
bis +32767 beschreiben."
Zwei Sᅵtze, zwei Fehler.
Stefan
Dr4x
Der minimale Wertebereich ist -32767 .. +32767. Eine Minimalgrᅵᅵe in
Bytes wird nicht gefordert. Auf dem Motorola 56000 reicht ein Byte, da
das dort 24 Bits hat.
Letztlich finde ich mit drei Sekunden Suche in meinem Newsspool einen
Verriss von 2006, <x3BD6...@ID-80798.user.dfncis.de>, und beim ersten
ᅵberfliegen gilt der noch. Der Fairness halber sei gesagt, dass es
durchaus schlechteres gibt als das "openbook"; die Tatsache, dass ein
Byte nicht unbedingt 8 Bit haben muss (sonst wᅵrde es ja Oktett heiᅵen)
wird immerhin erwᅵhnt.
Stefan
Fᅵr mich ist das wichtig zu wissen da ich nichts Falsches lernen mᅵchte.
> Stefan Reuther schrieb:
>> Der minimale Wertebereich ist -32767 .. +32767. Eine Minimalgrᅵᅵe in
>> Bytes wird nicht gefordert. Auf dem Motorola 56000 reicht ein Byte, da
>> das dort 24 Bits hat.
>
> Ich habe zwar nicht die groᅵe Ahnung, aber wenn mit dem Zweierkomplement
> http://de.wikipedia.org/wiki/Zweierkomplement gerechnet wird dann ist
> doch der Wertebereich fᅵr 16bit von -32768 bis +32767 da hier die 0 nur
> positiv angesehen wird.
Wie du schon schreibst: *wenn* mit dem Zweierkomplement gerechnet wird.
C fordert aber nicht, dass im Zweierkomplement gerechnet wird.
Und eh mir hier jemand Pedanterie vorwirft: man kann eine Menge
nᅵtzlichen Code schreiben, ohne Annahmen wie "ein int hat zwei Bytes"
oder "ein Byte hat 8 Bits" oder "Zweierkomplement" zu nutzen.
Stefan
Und der Standard legt sich eben nicht aud dieses Zweierkomplement fest.
Tschᅵ, Jojo
Dr4x <Dr...@gmx.de> wrote:
> Stefan Reuther schrieb:
>> Dr4x wrote:
>>> Stefan Reuther schrieb:
>>>> "5.2 Der Datentyp »int« (Integer)
>>>> Der Datentyp int muss, gemäß ANSI C, mindestens eine Größe von zwei Byte
>>>> aufweisen. Mit diesen zwei Bytes lässt sich ein Zahlenraum von -32768
>>>> bis +32767 beschreiben."
>>>> Zwei Sätze, zwei Fehler.
>>> Da ich auch noch C lerne würde ich gerne wissen welche zwei Fehler das
>>> sind. Dankeschön
>> Der minimale Wertebereich ist -32767 .. +32767. Eine Minimalgröße in
>> Bytes wird nicht gefordert. Auf dem Motorola 56000 reicht ein Byte, da
>> das dort 24 Bits hat.
> Ich habe zwar nicht die große Ahnung, aber wenn mit dem Zweierkomplement
> http://de.wikipedia.org/wiki/Zweierkomplement gerechnet wird dann ist
> doch der Wertebereich für 16bit von -32768 bis +32767 da hier die 0 nur
> positiv angesehen wird.
Der C-Standard fordert kein Zweierkomplement. Einerkomplement ist ebenfalls
moeglich, und dann waere der Wertebereich bei 16Bit-ints nur -32767 - 32767.
Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Ok, dann sind also die Wertangaben rein abhängig von der Implementierung.
> Dr4x wrote:
>> Stefan Reuther schrieb:
>>> "5.2 Der Datentyp »int« (Integer)
>>> Der Datentyp int muss, gemäß ANSI C, mindestens eine Größe von zwei Byte
>>> aufweisen. Mit diesen zwei Bytes lässt sich ein Zahlenraum von -32768
>>> bis +32767 beschreiben."
>>>
>>> Zwei Sätze, zwei Fehler.
>>
>> Da ich auch noch C lerne würde ich gerne wissen welche zwei Fehler das
>> sind. Dankeschön
>
> Der minimale Wertebereich ist -32767 .. +32767. Eine Minimalgröße in
> Bytes wird nicht gefordert.
Das ist auch unnötig, denn für diesen Wertebereich benötigt man zur
dualen Darstellung 16 binäre Stellen -- mithin 16 Bits, die solche
Werte effektiv abbilden. Da ein Byte seit mindestens 40 Jahren aus
acht Speicherbits besteht, sind also -- genau wie oben geschrieben --
mindestens zwei Bytes für den Datentyp "int" vonnöten.
Natürlich kann ein Byte mehr oder weniger als 8 Bits enthalten:
die meisten hochwertigen RAM-Riegel benutzen mindestens 1-2 Bits
zusätzlich pro 8-bit-Byte, um Speicherfehler zu erkennen oder gar
zu beheben (Parity/ECC), ebenso andere Datenträger (von Floppy bis
CD/DVD) oder auch UARTs, und bei Microcontrollern (MCUs) kann ein
Byte auch mal aus keinem Bit bestehen, oder nur "hier und da" mal
einem -- aber wenn es um Datenspeicherung geht, hat ein Byte netto
*immer* acht signifikante Bits.
> Auf dem Motorola 56000 reicht ein Byte, da
> das dort 24 Bits hat.
Nein, das ist dort die Größe eines "Maschinenworts", d.h. die
kleinste physikalische Bitbreite, mit der die CPU selbst auf den
Speicher zugreifen kann. Der 56k ist ein spezialisierter Prozessor
(DSP), deshalb machen 24 Bits/3 Bytes als Speicher-Entität Sinn,
genau wie bei "jüngeren" Grafikchips (GPUs), die -- wenn auch aus
anderen Gründen -- immer vier Bytes adressieren, obwohl sie nur drei
davon brauchen (die "ganz modernen" GPUs benutzen das vierte Byte
optional für Alpha-Blending-Werte oder auch als Safeguards bei
Berechnungen, etc.).
> Letztlich finde ich mit drei Sekunden Suche in meinem Newsspool einen
> Verriss von 2006, <x3BD6...@ID-80798.user.dfncis.de>, und beim ersten
> Überfliegen gilt der noch. Der Fairness halber sei gesagt, dass es
> durchaus schlechteres gibt als das "openbook"; die Tatsache, dass ein
> Byte nicht unbedingt 8 Bit haben muss (sonst würde es ja Oktett heißen)
> wird immerhin erwähnt.
Immerhin! Den zweiten Fehler im zweiten Satz bist Du noch schuldig
geblieben, aber der hängt ja auch mit dem ersten eng zusammen, und
der ist kein wirklicher Fehler. Für mich kein Grund zum Verriß des
Buches, aber ich habe es auch nicht gelesen und mich nur auf Deine
Kritikpunkte bezogen.
Letztlich kann ein C-Lehrbuch ohnehin auch nur "Erste Hilfe" leisten;
entscheidend ist, daß man die Grundlagen versteht, ausprobiert und
praktisch übt, und akzeptiert, daß C ein Oberbegriff für eine Sprache
ist, die unterschiedliche Compiler-Hersteller nach Belieben und/oder
Notwendigkeit ergänzen -- und wie man diese Unterschiede nutzen kann,
ohne dabei auf Portabilität zu verzichten!
mike
> Stefan Reuther wrote:
>
>> Dr4x wrote:
^^^^
Hier bitte Realnamen einsetzen.
>>> Da ich auch noch C lerne würde ich gerne wissen welche zwei Fehler das
>>> sind. Dankeschön
>>
>> Der minimale Wertebereich ist -32767 .. +32767. Eine Minimalgröße in
>> Bytes wird nicht gefordert.
>
> Das ist auch unnötig, denn für diesen Wertebereich benötigt man zur
> dualen Darstellung 16 binäre Stellen -- mithin 16 Bits
Richtig.
> Da ein Byte seit mindestens 40 Jahren aus
> acht Speicherbits besteht
Aber das nicht mehr. "Byte" wird zwar in vielen Bereichen mit "Oktett"
gleichgesetzt, aber nicht in allen, insbesondere nicht in C, und das
auch schon seit 40 Jahren. Und ja, es gibt Implementierungen, bei denen
ein Byte mehr als 8 Bit hat.
> aber wenn es um Datenspeicherung geht, hat ein Byte netto
> *immer* acht signifikante Bits.
Was meinst Du mit "Datenspeicherung" im Zusammenhang mit C?
>> Auf dem Motorola 56000 reicht ein Byte, da
>> das dort 24 Bits hat.
>
> Nein, das ist dort die Größe eines "Maschinenworts", d.h. die
> kleinste physikalische Bitbreite, mit der die CPU selbst auf den
> Speicher zugreifen kann.
Und wenn sich ein C-Compiler genau daran hält und die Größe eines char
mit 24 Bit festlegt (was durchaus erlaubt ist), ist in dieser
Implementierung ein Byte genau 24 Bit groß.
> Den zweiten Fehler im zweiten Satz bist Du noch schuldig
> geblieben
Nein, ist er nicht (s.o.).
aber der hängt ja auch mit dem ersten eng zusammen
Inwiefern?
Gruß. Claus
Wir reden hier von C, oder? Da ist ein Byte "addressable unit of data
storage large enough to hold any member of the basic character set of
the execution environment". Das kommt der ursprünglichen Definition als
kleinste adressierbare Einheit schon recht nahe.
> Natürlich kann ein Byte mehr oder weniger als 8 Bits enthalten:
> die meisten hochwertigen RAM-Riegel benutzen mindestens 1-2 Bits
> zusätzlich pro 8-bit-Byte, um Speicherfehler zu erkennen oder gar
> zu beheben (Parity/ECC),
ECC-Bits sind ja für C nun genauso irrelevant wie die Tatsache, dass man
pro Bit 6 Transistoren in eine SRAM-Zelle baut.
>>Auf dem Motorola 56000 reicht ein Byte, da das dort 24 Bits hat.
>
> Nein, das ist dort die Größe eines "Maschinenworts", d.h. die
> kleinste physikalische Bitbreite, mit der die CPU selbst auf den
> Speicher zugreifen kann.
In C heißt der Datentyp dafür dann 'char' und enthält ein Byte. Die
Datentypen 'short' und 'int' sind auf dem 56k genau so ein Byte groß.
Hätte der C-Standard Oktetts gemeint, würde er von 'octets' reden. Tut
er aber nicht.
> Letztlich kann ein C-Lehrbuch ohnehin auch nur "Erste Hilfe" leisten;
> entscheidend ist, daß man die Grundlagen versteht, ausprobiert und
> praktisch übt, und akzeptiert, daß C ein Oberbegriff für eine Sprache
> ist, die unterschiedliche Compiler-Hersteller nach Belieben und/oder
> Notwendigkeit ergänzen -- und wie man diese Unterschiede nutzen kann,
> ohne dabei auf Portabilität zu verzichten!
Genau das lernt man mit einem C-Buch nicht, das einem gleich zum Anfang
beibringt, dass ein 'int' 2 Bytes groß sei.
Was ist so schwer daran, die Datentypen als "natürliche Zahlen mit
Wertebereich mindestens <....>, alles darüber hinaus ist undefiniert"
einzuführen? Ist doch völlig wumpe, ob das dann 1, 2, 3 oder 4 Bytes
sind: solange die Werte im Wertebereich bleiben, benimmt sich das alles
wie erwartet, wie Zweite-Klasse-Schulmathematik. Nebenbei erspart man
sich dann die Begründung, warum ein 'struct { char a; int b; }' eben
nicht 3 bzw. 5 Bytes groß ist.
Floating-Point dagegen wird dann üblicherweise lapidar als "Dezimalbruch
mit soundsoviel Stellen" eingeführt, ohne auf die wirklich wichtigen
Dinge wie den Unterschied zwischen Dezimal- und Binärbrüchen oder Effek-
te der Exponentialdarstellung (z.B. Genauigkeitsverlust bei Subtraktion)
einzugehen.
Stefan
Jein. Der Standard formuliert Miniamalanfroderungen, die sind für alle
gleich, Die Implementaion kann mehr liefern
Tschö, Jojo
> Michael Schumacher schrieb:
>> Stefan Reuther wrote:
>>> Dr4x wrote:
> ^^^^
>
> Hier bitte Realnamen einsetzen.
s/^^^^/$Realname/ ;-)
>>>> Da ich auch noch C lerne würde ich gerne wissen welche zwei
>>>> Fehler das sind. Dankeschön
>>>
>>> Der minimale Wertebereich ist -32767 .. +32767. Eine Minimalgröße
>>> in Bytes wird nicht gefordert.
>>
>> Das ist auch unnötig, denn für diesen Wertebereich benötigt man zur
>> dualen Darstellung 16 binäre Stellen -- mithin 16 Bits
>
> Richtig.
>
>> Da ein Byte seit mindestens 40 Jahren aus
>> acht Speicherbits besteht
>
> Aber das nicht mehr. "Byte" wird zwar in vielen Bereichen mit "Oktett"
> gleichgesetzt, aber nicht in allen, insbesondere nicht in C, und das
> auch schon seit 40 Jahren. Und ja, es gibt Implementierungen, bei denen
> ein Byte mehr als 8 Bit hat.
Beispiele für Hardware, bei der 1 Byte != 8 Bits ist, nannte ich ja,
aber ein HW-Byte und ein C-char sind sehr unterschiedliche Dinge.
Umgekehrt kennt C auch Bits bzw. Bitfelder, die die Hardware nicht
direkt adressieren können muß.
>> aber wenn es um Datenspeicherung geht, hat ein Byte netto
>> *immer* acht signifikante Bits.
>
> Was meinst Du mit "Datenspeicherung" im Zusammenhang mit C?
Daß z.B. "void *ptr = malloc (1000);" im Erfolgsfall einen Zeiger auf
1000 lineare "char"s zu je acht linearen Bits liefert, deren Zustand
individuell geändert werden kann -- was zwingend erfordert, daß
"sizeof(char) == 1" ist.
>>> Auf dem Motorola 56000 reicht ein Byte, da
>>> das dort 24 Bits hat.
>>
>> Nein, das ist dort die Größe eines "Maschinenworts", d.h. die
>> kleinste physikalische Bitbreite, mit der die CPU selbst auf den
>> Speicher zugreifen kann.
>
> Und wenn sich ein C-Compiler genau daran hält und die Größe eines
> char mit 24 Bit festlegt (was durchaus erlaubt ist), ist in dieser
> Implementierung ein Byte genau 24 Bit groß.
Bloß weil Flugzeuge ihren Kerosinvorrat in Pfund messen, hat der
Liter deswegen noch lange nicht ausgedient! :-)
Ein C-Compiler muß den Datentyp "char" mit /mindestens/ 8 Bits
implementieren, und er muß den Speicher auch via "char *" linear
adressieren können. Dennoch -- oder auch /gerade/ deswegen -- sind
C-"char"s und Hardware-Bytes eben unterschiedliche Dinge. Für alle
praktischen Zwecke gilt aber als Informationseinheit 1 Byte = 8 Bits.
>> Den zweiten Fehler im zweiten Satz bist Du noch schuldig
>> geblieben
>
> Nein, ist er nicht (s.o.).
"Doch!"
"Nein!!"
"Doch!!!"
"Nein!!!!"
"Oooh!!!!!" :-)
> aber der hängt ja auch mit dem ersten eng zusammen
>
> Inwiefern?
Der Buchautor ist von "int" >= 16 Bits >= 2 Bytes ausgegangen,
also von einem 8-bit-Byte. Physikalisch muß das nicht stimmen,
wie wir festgestellt haben, aber /logisch/ (also im Sinne von
"char := array[0..7] of bit") ist es für C immer korrekt, und
wer gerne portablen C-Code schreibt, sollte sich auch an acht
Bits pro "char" halten, weil das die garantierte Mindestgröße
für diesen Datentyp ist.
mike
> Claus Reibenstein wrote:
>
>> Michael Schumacher schrieb:
>>
>>> aber wenn es um Datenspeicherung geht, hat ein Byte netto
>>> *immer* acht signifikante Bits.
>>
>> Was meinst Du mit "Datenspeicherung" im Zusammenhang mit C?
>
> Daß z.B. "void *ptr = malloc (1000);" im Erfolgsfall einen Zeiger auf
> 1000 lineare "char"s zu je acht linearen Bits liefert, deren Zustand
Falsch. malloc(1000) liefert Dir 1000 Bytes (oder 1000 chars; die
Bezeichnungen sind in C austauschbar), aber nicht zwingend 8000 Bits.
> individuell geändert werden kann -- was zwingend erfordert, daß
> "sizeof(char) == 1" ist.
Das fordert der Standard sowieso (deswegen "austauschbar").
>> Und wenn sich ein C-Compiler genau daran hält und die Größe eines
>> char mit 24 Bit festlegt (was durchaus erlaubt ist), ist in dieser
>> Implementierung ein Byte genau 24 Bit groß.
>
> Bloß weil Flugzeuge ihren Kerosinvorrat in Pfund messen, hat der
> Liter deswegen noch lange nicht ausgedient! :-)
Wie meinen?
> Ein C-Compiler muß den Datentyp "char" mit /mindestens/ 8 Bits
> implementieren, und er muß den Speicher auch via "char *" linear
> adressieren können. Dennoch -- oder auch /gerade/ deswegen -- sind
> C-"char"s und Hardware-Bytes eben unterschiedliche Dinge. Für alle
> praktischen Zwecke gilt aber als Informationseinheit 1 Byte = 8 Bits.
Das meinte ich mit '"Byte" wird zwar in vielen Bereichen mit "Oktett"
gleichgesetzt'. Nichtsdestotrotz hat C seine eigene, davon abweichende
Definition.
>>> Den zweiten Fehler im zweiten Satz bist Du noch schuldig
>>> geblieben
>>
>> Nein, ist er nicht (s.o.).
>
> "Doch!"
Ich habe den entsprechenden Absatz oben zwar zitiert, aber extra für
Dich nehme ich ihn gerne einmal auseinander:
1) "Der minimale Wertebereich ist -32767 .. +32767". Das Buch gab die
untere Grenze mit -32768 an.
2) "Eine Minimalgröße in Bytes wird nicht gefordert". Das Buch
behauptete, ein int wäre mindestens 2 Byte groß.
Welchen davon hast Du gemeint? Oder hast Du noch einen dritten, von dem
wir nichts wissen?
>> aber der hängt ja auch mit dem ersten eng zusammen
>>
>> Inwiefern?
>
> Der Buchautor ist von "int" >= 16 Bits >= 2 Bytes ausgegangen,
> also von einem 8-bit-Byte.
Ich sehe keinen Zusammenhang zwischen -32768 vs. -32767 und 8 Bit.
> Physikalisch muß das nicht stimmen,
> wie wir festgestellt haben, aber /logisch/ (also im Sinne von
> "char := array[0..7] of bit") ist es für C immer korrekt
Es muss auch logisch nicht stimmen. Der Standard fordert nirgends, dass
ein Byte genau 8 Bit haben muss. Er fordert in 5.2.4.2.1 lediglich, dass
ein Byte _mindestens_ 8 Bit groß sein muss, und erwähnt dort
ausdrücklich, dass jede Implementierung einen größeren Wert festlegen
kann ("Their implementation-defined values shall be equal or greater in
magnitude (absolute value) to those shown, with the same sign"). Den
tatsächlichen Wert kann man der Konstante CHAR_BIT entnehmen.
> wer gerne portablen C-Code schreibt, sollte sich auch an acht
> Bits pro "char" halten, weil das die garantierte Mindestgröße
> für diesen Datentyp ist.
Oder er hält sich an CHAR_BIT.
Gruß. Claus
Falsch, nicht 8, sondern CHAR_BIT viele. (#include limits.h)
> individuell geändert werden kann -- was zwingend erfordert, daß
> "sizeof(char) == 1" ist.
Richtig
Tschö, Jojo
Michael Schumacher <mi...@gmx.de> wrote:
> Beispiele für Hardware, bei der 1 Byte != 8 Bits ist, nannte ich ja,
> aber ein HW-Byte und ein C-char sind sehr unterschiedliche Dinge.
Ein "unsigned char" ist in C der Datentyp, der genau ein (C-) Byte auf-
nehmen kann. Zumindest "unsigned char" und "byte" sind in C also nicht
so unterschiedlich wie du glaubst ...
> Umgekehrt kennt C auch Bits bzw. Bitfelder, die die Hardware nicht
> direkt adressieren können muß.
Und?
>>> aber wenn es um Datenspeicherung geht, hat ein Byte netto
>>> *immer* acht signifikante Bits.
>> Was meinst Du mit "Datenspeicherung" im Zusammenhang mit C?
> Daß z.B. "void *ptr = malloc (1000);" im Erfolgsfall einen Zeiger auf
> 1000 lineare "char"s zu je acht linearen Bits liefert, deren Zustand
> individuell geändert werden kann -- was zwingend erfordert, daß
> "sizeof(char) == 1" ist.
sizeof(char) ist per Definition *immer* 1, der von dir genannte malloc-
Aufruf liefert jedoch nicht 1000 "Oktetts" sondern 10000 (unsigned) chars
(die eben nicht alle 8 Bit breit sein muessen: der Standard fordert ledig-
lich, dass sie *mindestens* je 8 Bit breit sind).
>>>> Auf dem Motorola 56000 reicht ein Byte, da
>>>> das dort 24 Bits hat.
>>> Nein, das ist dort die Größe eines "Maschinenworts", d.h. die
>>> kleinste physikalische Bitbreite, mit der die CPU selbst auf den
>>> Speicher zugreifen kann.
>> Und wenn sich ein C-Compiler genau daran hält und die Größe eines
>> char mit 24 Bit festlegt (was durchaus erlaubt ist), ist in dieser
>> Implementierung ein Byte genau 24 Bit groß.
> Bloß weil Flugzeuge ihren Kerosinvorrat in Pfund messen, hat der
> Liter deswegen noch lange nicht ausgedient! :-)
Es gibt auch standardkonforme C-Implementierungen, bei denen sizeof(long)
den Wert 1 hat. Rate mal, wie breit dort denn ein (C-) Byte ist?
> Ein C-Compiler muß den Datentyp "char" mit /mindestens/ 8 Bits
> implementieren, und er muß den Speicher auch via "char *" linear
> adressieren können. Dennoch -- oder auch /gerade/ deswegen -- sind
> C-"char"s und Hardware-Bytes eben unterschiedliche Dinge. Für alle
> praktischen Zwecke gilt aber als Informationseinheit 1 Byte = 8 Bits.
Nicht fuer den C-Standard, der die Diskussionsgrundlage in dieser Gruppe
darstellt ...
> Der Buchautor ist von "int" >= 16 Bits >= 2 Bytes ausgegangen,
> also von einem 8-bit-Byte. Physikalisch muß das nicht stimmen,
> wie wir festgestellt haben, aber /logisch/ (also im Sinne von
> "char := array[0..7] of bit") ist es für C immer korrekt,
Wenn du dieser Ueberzeugung bist, dann belege das bitte anhand des
C-Standards (oder gib gleich auf, denn das wird dir nicht gelingen).
> und wer gerne portablen C-Code schreibt, sollte sich auch an acht
> Bits pro "char" halten, weil das die garantierte Mindestgröße
> für diesen Datentyp ist.
Eben *weil* das die Mindestegroesse ist, sollte er sich nicht an "char
hat 8 Bit" sondern an "char hat Mindestens 8 Bit, es kann aber auch mehr
sein" gewoehnen. Der genaue Wert wird in einer hosted Implementation
i.a. in der include-Datei "limits.h" durch "CHAR_BIT" gegeben.
Ne, nur 1000
> (unsigned) chars (die eben nicht alle 8 Bit breit sein muessen: der
> Standard fordert ledig- lich, dass sie *mindestens* je 8 Bit breit
> sind).
Tschö, Jojo
Stefan Reuther schrieb:
[...]
> Floating-Point dagegen wird dann üblicherweise lapidar als "Dezimalbruch
> mit soundsoviel Stellen" eingeführt, ohne auf die wirklich wichtigen
> Dinge wie den Unterschied zwischen Dezimal- und Binärbrüchen oder Effek-
> te der Exponentialdarstellung (z.B. Genauigkeitsverlust bei Subtraktion)
> einzugehen.
Wenn ich mir das recht überlege, dann wurde "bei uns"[tm]
zunächst auf Papier mit dem Stift (wie altmodisch) per Hand
tatsächlich ganze Zahlen vom Dezimalsystem ins Hexadezimal,
ins Binärsystem und ins Oktalsystem umgerechnet.
Dann ein paar Rechenübungen im b und b-1 Komplement betrieben.
(b für Basis, z.B. b=2, b=3, b=8, b=10, b=16)
Auch wurden Berechnungen mit IEEE 754 Zahlen per Hand gefertigt.
Dann hatte man 1-0-Zeichenketten mal als Ganzezahlen (mit und ohne VZ)
und als IEEE 754 Zahlen zu interpretieren.
Neuerdings kommt dann noch die handschriftliche Codierungsübung
zu UTF8 hinzu, d.h. erkenne welche 1-0-Zeichenketten
entsprechend gültig ist.
Bei UTF8 geht man ja tatsächlich von Folgen von 8-Bit aus.
Wenn man nun, und das muss ja auch mit C gehen, UTF8 implementieren
will, dann muss der Typ tatsächlich in 8-bit gruppiert werden
oder man muss dafür sorgen, dass von jedem Byte falls CHAR_BIT > 8
tatsächlich _immer_ nur die Bits 0 bis 7 ausgewertet oder benutzt werden.
Ob man sich darauf verlassen kann, dass es stets gilt:
byte=1*CHAR_BIT
word=2*byte
dword=2*word
qword=4*word
Sei dahingestellt...
Aber dass man tatsächlich nur Bits 0 bis 7 eines Chars
(die ja stets bei einem Char existieren müssen) benutzen sollte,
sobald die Informationen das Programm (und damit C und seinen Standard)
verlassen, sollte wohl jedem einleuchten.
Gruß Robert
Naja, das sind zwar nützliche Fertigkeiten, aber für das Rechnen mit
Integern braucht man die nicht.
> Neuerdings kommt dann noch die handschriftliche Codierungsübung
> zu UTF8 hinzu, d.h. erkenne welche 1-0-Zeichenketten
> entsprechend gültig ist.
>
> Bei UTF8 geht man ja tatsächlich von Folgen von 8-Bit aus.
Deswegen heißt es ja UTF-8. Hat man nur 7 Bit, nimmt man UTF-7. Hat man
9 Bit, nimmt man UTF-9. Hat man 16 Bit, nimmt man UTF-16.
> Wenn man nun, und das muss ja auch mit C gehen, UTF8 implementieren
> will, dann muss der Typ tatsächlich in 8-bit gruppiert werden
> oder man muss dafür sorgen, dass von jedem Byte falls CHAR_BIT > 8
> tatsächlich _immer_ nur die Bits 0 bis 7 ausgewertet oder benutzt werden.
>
> Ob man sich darauf verlassen kann, dass es stets gilt:
> byte=1*CHAR_BIT
> word=2*byte
> dword=2*word
> qword=4*word
"word" und "dword" haben im Kontext von C keine Bedeutung. Aber auf eine
bestimmte Relation von short, int und long zu char kannst du dich nicht
verlassen.
Du kannst int8_t & Co. aus <stdint.h> benutzen. Damit wird dein Programm
eben nur auf Maschinen kompilieren, die 8-bit-Typen haben, dort wird es
aber das gewünschte Verhalten zeigen.
Stefan
>> Beispiele für Hardware, bei der 1 Byte != 8 Bits ist, nannte ich ja,
>> aber ein HW-Byte und ein C-char sind sehr unterschiedliche Dinge.
>
> Ein "unsigned char" ist in C der Datentyp, der genau ein (C-) Byte auf-
> nehmen kann. Zumindest "unsigned char" und "byte" sind in C also nicht
> so unterschiedlich wie du glaubst ...
Äh, doch -- deshalb ja auch diese Diskussion! ;^)
>> Umgekehrt kennt C auch Bits bzw. Bitfelder, die die Hardware nicht
>> direkt adressieren können muß.
>
> Und?
Programmiersprachen und Hardware sind unterschiedliche Welten, auch
wenn es durchaus breite Übereinstimmungen geben kann.
>>>> aber wenn es um Datenspeicherung geht, hat ein Byte netto
>>>> *immer* acht signifikante Bits.
>>> Was meinst Du mit "Datenspeicherung" im Zusammenhang mit C?
>> Daß z.B. "void *ptr = malloc (1000);" im Erfolgsfall einen Zeiger auf
>> 1000 lineare "char"s zu je acht linearen Bits liefert, deren Zustand
>> individuell geändert werden kann -- was zwingend erfordert, daß
>> "sizeof(char) == 1" ist.
>
> sizeof(char) ist per Definition *immer* 1, der von dir genannte malloc-
> Aufruf liefert jedoch nicht 1000 "Oktetts" sondern 10000 (unsigned) chars
> (die eben nicht alle 8 Bit breit sein muessen: der Standard fordert ledig-
> lich, dass sie *mindestens* je 8 Bit breit sind).
Siehst Du, und genau das ist der Punkt: ich habe geschrieben, daß
"malloc (1000)" eine Adresse auf 1000 lineare "char"s zu je acht
linearen Bits liefert (das "mindestens acht Bit pro char" wollte
ich hier nicht wiederholen, weil (nicht nur) ich das im Zusammenhang
mit "char" bereits zuvor erwähnt hatte). Und jetzt bringst Du auf
einmal "Oktetts" ins Spiel, aber da war ja noch was:
>>>>> Auf dem Motorola 56000 reicht ein Byte, da
>>>>> das dort 24 Bits hat.
>>>> Nein, das ist dort die Größe eines "Maschinenworts", d.h. die
>>>> kleinste physikalische Bitbreite, mit der die CPU selbst auf den
>>>> Speicher zugreifen kann.
>>> Und wenn sich ein C-Compiler genau daran hält und die Größe eines
>>> char mit 24 Bit festlegt (was durchaus erlaubt ist), ist in dieser
>>> Implementierung ein Byte genau 24 Bit groß.
>> Bloß weil Flugzeuge ihren Kerosinvorrat in Pfund messen, hat der
>> Liter deswegen noch lange nicht ausgedient! :-)
>
> Es gibt auch standardkonforme C-Implementierungen, bei denen sizeof(long)
> den Wert 1 hat. Rate mal, wie breit dort denn ein (C-) Byte ist?
>
>> Ein C-Compiler muß den Datentyp "char" mit /mindestens/ 8 Bits
>> implementieren, und er muß den Speicher auch via "char *" linear
>> adressieren können. Dennoch -- oder auch /gerade/ deswegen -- sind
>> C-"char"s und Hardware-Bytes eben unterschiedliche Dinge. Für alle
>> praktischen Zwecke gilt aber als Informationseinheit 1 Byte = 8 Bits.
>
> Nicht fuer den C-Standard, der die Diskussionsgrundlage in dieser Gruppe
> darstellt ...
Der C-Standard kennt aber nun mal kein Byte, bzw. einen vorgegebenen
Datentyp "byte", der einem 8-bit-Byte entspricht! C kennt nur "char"
-- und ob ein "char" tatsächlich einem Byte entspricht, ist eine Frage
der Hardware und der C-Implementierung. Falls etwa die Hardware nur
24-bit-Worte atomar adressieren kann, kann C den Basis-Datentyp "char"
auch nur so implementieren. Ein "char" ist dann eben /kein/ Byte, aber
dennoch besteht ein 24-bit-Maschinenwort aus drei Bytes zu je acht Bits,
selbst wenn diese (Bits und/oder Bytes) nicht einzeln adressierbar, und
CPU-intern nicht mal "verdrahtet" sein sollten (was gerne gemacht wird,
um aktuell Kosten zu sparen und gleichzeichtig zukünftige Erweiterungen
zu erlauben). Denn als Informationseinheit besteht ein Byte nun mal aus
acht informationstragenden Bits, auch wenn die physikalische Speicherung
und Datensicherung mehr als acht Bits erfordert (-> Meta-Information).
Wenn ein C-Buch-Autor von einem 8-bit-Byte ausgeht, einem C-"int" deren
mindestens zwei zuordnet, und mit dem Wertebereich [-32768..32767] eine
Zahlenverarbeitung und -darstellung im 2er-Komplement voraussetzt, dann
erschlägt er 99.999% aller real existierenden C-Implementierungen und
CPUs/MCUs, mit denen Normalsterbliche jemals in Kontakt kommen könnten.
Und die Unsterblichen Supermänner[tm] lesen dieses Buch sowieso nicht.
Diese Diskussion mag hoffentlich nützliche Seiteneffekte bewirken, aber
der Korintenfaktor ist extrem hoch (wie beim Elektrolehrling anbetrachts
einer 220V-Steckdose: "Nein, das sind keine 220V -- das ist Wurzel zwo
mal mehr!").
UND JA, ICH WEISS, DASS MAN KORINTEN MIT H SCHEISST!
mi":-)"ke
> Der C-Standard kennt aber nun mal kein Byte, bzw. einen vorgegebenen
> Datentyp "byte", der einem 8-bit-Byte entspricht! C kennt nur "char" --
> und ob ein "char" tatsächlich einem Byte entspricht, ist eine Frage der
> Hardware und der C-Implementierung.
Der Standard kennt Bytes:
3.6
[#1] byte
addressable unit of data storage large enough to hold any
member of the basic character set of the execution
environment
[#2] NOTE 1 It is possible to express the address of each
individual byte of an object uniquely.
[#3] NOTE 2 A byte is composed of a contiguous sequence of
bits, the number of which is implementation-defined. The
least significant bit is called the low-order bit; the most
significant bit is called the high-order bit.
Und ein char entspricht einem Byte.
3.7
[#1] character
<abstract> member of a set of elements used for the
organization, control, or representation of data
3.7.1
[#1] character
single-byte character
<C> bit representation that fits in a byte
3.7.2
[#1] multibyte character
sequence of one or more bytes representing a member of the
extended character set of either the source or the execution
environment
[#2] NOTE The extended character set is a superset of the
basic character set.
Grüße,
Erich
--
EFEU 3.2 is released!
Get the open source from http://efeu.cybertec.at.
Michael Schumacher <mi...@gmx.de> wrote:
> Juergen Ilse wrote:
>>>>> aber wenn es um Datenspeicherung geht, hat ein Byte netto
>>>>> *immer* acht signifikante Bits.
>>>> Was meinst Du mit "Datenspeicherung" im Zusammenhang mit C?
>>> Daß z.B. "void *ptr = malloc (1000);" im Erfolgsfall einen Zeiger auf
>>> 1000 lineare "char"s zu je acht linearen Bits liefert, deren Zustand
>>> individuell geändert werden kann -- was zwingend erfordert, daß
>>> "sizeof(char) == 1" ist.
>>
>> sizeof(char) ist per Definition *immer* 1, der von dir genannte malloc-
>> Aufruf liefert jedoch nicht 1000 "Oktetts" sondern 1000 (unsigned) chars
>> (die eben nicht alle 8 Bit breit sein muessen: der Standard fordert ledig-
>> lich, dass sie *mindestens* je 8 Bit breit sind).
> Siehst Du, und genau das ist der Punkt: ich habe geschrieben, daß
> "malloc (1000)" eine Adresse auf 1000 lineare "char"s zu je acht
> linearen Bits liefert (das "mindestens acht Bit pro char" wollte
> ich hier nicht wiederholen, weil (nicht nur) ich das im Zusammenhang
> mit "char" bereits zuvor erwähnt hatte).
Das ist aber gerade der relevante Punkt: Nicht 1000 lineare "char"s zu je
acht Bit, sondern 1000 lineare "char"s (*ohne* die nicht zwingend zutref-
fende Groessenangabe). Es gibt C-Implementierungen, bei denen ein char eben
*nicht* 8 Bit breit ist (sondern 16, 24 oder gar 32 Bit). Es ist schlicht
ein *Fehler*, davon auszugehen, dass ein char *genau* 8 Bit haette. Es waere
sogar ein Fehler, davon auszugehen, dass der "positive Wertebereich" von long
groesser waere als der Wertebereich von unsigned char: Es gibt mindestens
eine Implementierung, bei der der "positive Wertebereich von long" nur bis
2^31-1 reicht, waehrend der Wertebereich von unsingned char bis 2^32-1 reicht.
> Und jetzt bringst Du auf einmal "Oktetts" ins Spiel,
Die Oktetts hast du dadurch ins Spiel gebracht, dass du zwingend von 8-Bit
Bytes (oder "char"s) ausgegangen bist ...
> aber da war ja noch was:
>>> Ein C-Compiler muß den Datentyp "char" mit /mindestens/ 8 Bits
>>> implementieren, und er muß den Speicher auch via "char *" linear
>>> adressieren können. Dennoch -- oder auch /gerade/ deswegen -- sind
>>> C-"char"s und Hardware-Bytes eben unterschiedliche Dinge. Für alle
>>> praktischen Zwecke gilt aber als Informationseinheit 1 Byte = 8 Bits.
>> Nicht fuer den C-Standard, der die Diskussionsgrundlage in dieser Gruppe
>> darstellt ...
> Der C-Standard kennt aber nun mal kein Byte, bzw. einen vorgegebenen
> Datentyp "byte", der einem 8-bit-Byte entspricht!
Im C99-Standard steht unter 3.6 der folgende Text:
3.6
1 byte
addressable unit of data storage large enough to hold any member
of the basic character set of the execution environment
2 NOTE 1 It is possible to express the address of each individual
byte of an object uniquely.
3 NOTE 2 A byte is composed of a contiguous sequence of bits, the
number of which is implementation defined. The least significant
bit is called the low-order bit; the most significant bit is called
the high-order bit.
Offensichtlich kennt der C-Standard also sehr wohl ein Byte ...
> C kennt nur "char" -- und ob ein "char" tatsächlich einem Byte entspricht,
> ist eine Frage der Hardware und der C-Implementierung.
Und wieder daneben. In 3.7 findet man den folgenden Text:
3.7
1 character
〈abstract〉 member of a set of elements used for the organization,
control, or representation of data
3.7.1
1 character
single-byte character〈C〉 bit representation that fits in a byte
Auch mit dieser Behauptung scheinst du also daneben zu liegen ...
> Wenn ein C-Buch-Autor von einem 8-bit-Byte ausgeht, einem C-"int" deren
> mindestens zwei zuordnet, und mit dem Wertebereich [-32768..32767] eine
> Zahlenverarbeitung und -darstellung im 2er-Komplement voraussetzt, dann
> erschlägt er 99.999% aller real existierenden C-Implementierungen und
> CPUs/MCUs, mit denen Normalsterbliche jemals in Kontakt kommen könnten.
> Und die Unsterblichen Supermänner[tm] lesen dieses Buch sowieso nicht.
Von einem *guten* C-Buch sollte man erwarten, dass alle nicht auf 100% der
standardkonformen C-Implementierungen zutreffenden Aussagen deutlich als
"nicht zwingend fuer alle Implementierungen zutreffend" markiert sind oder
gleich ganz weggelassen werden.
> Diese Diskussion mag hoffentlich nützliche Seiteneffekte bewirken, aber
> der Korintenfaktor ist extrem hoch
Diejenigen, die dir widersprechen, koennen ihre Aussagen anhand des
C-Standards belegen (siehe oben) ganz im Gegensatz zu dir. Also hat
das alles nicht mit Korithenkackerei zu tun sondern schlicht mit "trifft
zu" oder "trifft nicht unbedingt zu". Deine Aussagen in dieser Diskussion
fallen vorwiegend in letztere Kathegorie.
> UND JA, ICH WEISS, DASS MAN KORINTEN MIT H SCHEISST!
Man schreibt das Wort allerdings auch mit 2 "n" ...
;-)
> Juergen Ilse wrote:
>
>>> Beispiele für Hardware, bei der 1 Byte != 8 Bits ist, nannte ich ja,
>>> aber ein HW-Byte und ein C-char sind sehr unterschiedliche Dinge.
>>
>> Ein "unsigned char" ist in C der Datentyp, der genau ein (C-) Byte auf-
>> nehmen kann. Zumindest "unsigned char" und "byte" sind in C also nicht
>> so unterschiedlich wie du glaubst ...
>
> Äh, doch -- deshalb ja auch diese Diskussion! ;^)
Dann erläutere doch bitte mal den Unterschied, den Du zu sehen glaubst,
und belege ihn anhand des C-Standards.
>>> Umgekehrt kennt C auch Bits bzw. Bitfelder, die die Hardware nicht
>>> direkt adressieren können muß.
>>
>> Und?
>
> Programmiersprachen und Hardware sind unterschiedliche Welten, auch
> wenn es durchaus breite Übereinstimmungen geben kann.
Was für diese Diskussion absolut belanglos ist. Hier geht es um die
Sprache C, nicht um irgendwelche Hardware.
>>> Ein C-Compiler muß den Datentyp "char" mit /mindestens/ 8 Bits
>>> implementieren, und er muß den Speicher auch via "char *" linear
>>> adressieren können. Dennoch -- oder auch /gerade/ deswegen -- sind
>>> C-"char"s und Hardware-Bytes eben unterschiedliche Dinge. Für alle
>>> praktischen Zwecke gilt aber als Informationseinheit 1 Byte = 8 Bits.
Wer redet denn von Hardware-Bytes? Dies hier ist eine C-Gruppe. Wenn
hier von Bytes die Rede ist, dann sind damit Bytes im Sinne von C gemeint.
Abgesehen davon wurde hier bereits erwähnt, dass es Hardware gibt, die
eine andere Byte-Größe benutzt.
>> Nicht fuer den C-Standard, der die Diskussionsgrundlage in dieser Gruppe
>> darstellt ...
>
> Der C-Standard kennt aber nun mal kein Byte
,---------- ISO/IEC 9899:1999
| 3.6 byte
| addressable unit of data storage large enough to hold any member of
| the basic character set of the execution environment
`----------
> bzw. einen vorgegebenen
> Datentyp "byte", der einem 8-bit-Byte entspricht!
Hat auch niemand behauptet.
> C kennt nur "char"
> -- und ob ein "char" tatsächlich einem Byte entspricht, ist eine Frage
> der Hardware und der C-Implementierung.
,---------- ISO/IEC 9899:1999
| 6.5.3.4 The sizeof operator
| 1 [...]
| 2 The sizeof operator yields the size (in bytes) [...]
| 3 When applied to an operand that has type char, unsigned char, or
| signed char, (or a qualified version thereof) the result is 1.
| [...]
`----------
Der Standard legt somit eindeutig fest, _dass_ ein char einem Byte
entspricht. Wie groß dieses Byte ist, ist _ausschließlich_ eine Frage
der Implementierung. Die darunter liegende Hardware und ihre
(Hardware-)Bytes sind dabei vollkommen irrelevant.
> Falls etwa die Hardware nur
> 24-bit-Worte atomar adressieren kann, kann C den Basis-Datentyp "char"
> auch nur so implementieren.
Warum?
> Ein "char" ist dann eben /kein/ Byte,
Im Sinne von C ist es sehr wohl ein Byte (s.o.).
> Wenn ein C-Buch-Autor von einem 8-bit-Byte ausgeht, einem C-"int" deren
> mindestens zwei zuordnet, und mit dem Wertebereich [-32768..32767] eine
> Zahlenverarbeitung und -darstellung im 2er-Komplement voraussetzt, dann
> erschlägt er 99.999% aller real existierenden C-Implementierungen und
> CPUs/MCUs, mit denen Normalsterbliche jemals in Kontakt kommen könnten.
Ich weiß nicht, welche C-Implementierungen Du kennst. Hier wurden aber
bereits mehrfach welche genannt, die eben kein 8-Bit-Byte verwenden, und
deren Marktanteil dürfte deutlich über 0,001% liegen.
Unabhängig davon hat ein Fachbuch exakt zu sein. Die obigen Angaben sind
es nicht.
> Und die Unsterblichen Supermänner[tm] lesen dieses Buch sowieso nicht.
Ich halte mich weder für unsterblich noch für einen Supermann, sondern
für einen ganz normalen C-Programmierer.
> Diese Diskussion mag hoffentlich nützliche Seiteneffekte bewirken, aber
"Seiteneffekte" - ich _hasse_ dieses Unwort. Die korrekte deutsche
Übersetzung für "side effect" lautet "Nebenwirkung".
Gruß. Claus
> Michael Schumacher schrieb:
>> Juergen Ilse wrote:
>>
>>>> Beispiele für Hardware, bei der 1 Byte != 8 Bits ist, nannte ich ja,
>>>> aber ein HW-Byte und ein C-char sind sehr unterschiedliche Dinge.
>>>
>>> Ein "unsigned char" ist in C der Datentyp, der genau ein (C-) Byte auf-
>>> nehmen kann. Zumindest "unsigned char" und "byte" sind in C also nicht
>>> so unterschiedlich wie du glaubst ...
>>
>> Äh, doch -- deshalb ja auch diese Diskussion! ;^)
>
> Dann erläutere doch bitte mal den Unterschied, den Du zu sehen glaubst,
> und belege ihn anhand des C-Standards.
C definiert sich sein eigenes "Byte" in Form eines "char"; in der
"restlichen" IT-Welt wird ein Byte (als Informationseinheit) als
eine Folge von acht informationstragenden Bits beschrieben, die
eine logische Einheit bilden. Dieser Schiedunter ist vergleichbar
mit der Sichtweise von Unix hinsichtlich I/O: eine Datei ist eine
Folge einzelner Bytes (zu je acht Bits), auch wenn der eigentliche
Datenträger mehr oder weniger physikalische Bits zur Speicherung
benötigt. Dito serielle Verbindungen, die logisch Byte-weise (mit
je acht Bit) bedient werden, auch wenn physikalisch (und in diesem
Fall sogar logisch) weniger oder mehr als acht Bits über die TxD-
und RxD-Leitungen wandern. Es sind eben verschiedene Definitionen,
so wie das Grammgewicht eines Pfunds in D und GB.
Wenn Du wissen willst, wie "die Welt" außerhalb von C ein Byte
als Informationseinheit definiert, hier URLbar Lesenswertes (und
bitte beachten: es geht um die *heute* *gängige* Definition!):
- <http://www.catb.org/~esr/jargon/html/B/byte.html>
- <http://www.linfo.org/byte.html>
- <http://lexikon.martinvogel.de/byte.html>
- <http://www.bullhost.de/b/byte.html>
- <http://www.computerlexikon.com/definition-byte>
- <http://www.bluray-disc.de/lexikon/byte>
- <http://woerterbuch.babylon.com/Byte>
- <http://cplus.about.com/od/glossar1/g/bytedefinition.htm>
- <http://de.wikipedia.org/wiki/Byte>
- u.v.a.m.
Nochmal: auch wenn der C-Standard seine eigene Vorstellung von
einem Byte hat (was ja durchaus in Ordnung geht!), deckt sich
diese nicht zwingend mit der gängigen Definition eines IT-Bytes:
eine tatsächliche C-Implementierung könnte selbst auf einem x86
den Typ "char" (mit sizeof(char, int, long) = 1) als 32- oder
gar 64-bit-Wort implementieren, und würde damit perfekt gültigen
-- vermutlich sogar recht flotten! -- Code produzieren. Dann
entspräche eben ein "C-Byte" vier oder acht Bytes, und zwar
*ungeachtet dessen*, ob die x86-Architektur tatsächlich auch
einzelne Bytes (zu jeweils acht Bits) adressieren kann -- und
das ist eben der von mir erwänhte Unterschied zwischen C-"char"s
und IT-Bytes.
Es mag nicht 100%-ig korrekt sein, C-"int"s mit zwei gekoppelten
IT-Bytes zu assoziieren, oder von einer CPU mit Zweierkomplement
auszugehen, aber das beschreibt nun mal die erdrückende Wahrheit,
und daß es auch Ausnahmen {gegeben hat,gibt,geben kann}, ist doch
noch lange kein Grund für den "totalen Verriß" eines C-Lehrbuchs!
Zumal jeder weiß, daß zur "Wahrheitsfindung" mindestens mal zwei
Quellen (möglichst unabhängig voneinander) nötig sind, und sich
"Wahrheiten" auch schon mal ändern können (-> Erdscheibe/-Kugel).
[...]
>> Diese Diskussion mag hoffentlich nützliche Seiteneffekte bewirken
>
> "Seiteneffekte" - ich _hasse_ dieses Unwort. Die korrekte deutsche
> Übersetzung für "side effect" lautet "Nebenwirkung".
Zu Risiken und ebendiesen befragen Sie bitte Ihren Arzt oder Ihren
Apotheker! :-)
mike
Michael Schumacher <mi...@gmx.de> wrote:
> C definiert sich sein eigenes "Byte" in Form eines "char"; in der
> "restlichen" IT-Welt wird ein Byte (als Informationseinheit) als
> eine Folge von acht informationstragenden Bits beschrieben, die
> eine logische Einheit bilden.
In einigen Bereichen der IT wird Byte manchmal als synonym fuer Oktett
verwendet, aber in dieser Gruppe (genauso wie in einem Buch, das sich
*ausdruecklich* mit C beschaeftigt) ist das irrelevant (bzw. sollte
irrelevant sein), denn Im C-Umfeld ist ein Byte *genau* *das* was der
C-Standard als Byte definiert. Die Definition wurd bereits genannt.
> Wenn Du wissen willst, wie "die Welt" außerhalb von C ein Byte
> als Informationseinheit definiert, hier URLbar Lesenswertes (und
> bitte beachten: es geht um die *heute* *gängige* Definition!):
Hier geht es aber nicht darum, wie irgend jemand in voellig anderen
Zusammenhaengen moeglicherweise ein Byte definiert. Von einem *guten*
Buch ueber die Sprache C sollte man auch erwarten, dass es die im
C-Standard verwendete Definition des Begriffs uebernimmt und dann
diese verwendet. Wenn man in einem solchen Buch tatsaechlich meint,
von einem Oktett schreiben zu muessen, sollte man auch diesen Begriff
statt des (im C-Umfeld dafuer nicht zwingend zutreffenden) Begriffs
"Byte" verwenden. Ein Buch ueber C, das nicht die in C ueblichen Be-
griffe und Definitionen verwendet, kann man beim besten Willen nicht
als "gut" bezeichnen (sondern eher als fehlerhaft).
> eine tatsächliche C-Implementierung könnte selbst auf einem x86
> den Typ "char" (mit sizeof(char, int, long) = 1) als 32- oder
> gar 64-bit-Wort implementieren, und würde damit perfekt gültigen
> -- vermutlich sogar recht flotten! -- Code produzieren. Dann
> entspräche eben ein "C-Byte" vier oder acht Bytes, und zwar
> *ungeachtet dessen*, ob die x86-Architektur tatsächlich auch
> einzelne Bytes (zu jeweils acht Bits) adressieren kann -- und
> das ist eben der von mir erwänhte Unterschied zwischen C-"char"s
> und IT-Bytes.
Es gibt mehr als nur eine Architektur, auf der 8 Bit nicht direkt
adressiert werden koennen (sondern die kleinste direkt adressierbare
Einheit eben aus 16, 24 oder gar 32 Bit besteht, oder bei manchen
speziellen CPUs sogar aus einem Bit ...), und fuer diese Architek-
turen gibt es standardkonforme C-Implementierungen (bei denen i.d.R.
ein Byte gemaess C-Standard *nicht* genau 8 Bit breit ist).
> Es mag nicht 100%-ig korrekt sein, C-"int"s mit zwei gekoppelten
> IT-Bytes zu assoziieren,
Es ist schlicht und ergreifend *falsch*, die Begriffe Oktett und Byte
im Zusammenhang mit der Sprache C gleichzusetzen, weil sie in diesem
Kontext schlicht nicht gleich *sind*.
> oder von einer CPU mit Zweierkomplement auszugehen,
Da der C-Standard sogar *ausdruecklich* auch Einerkomplement fuer eine
standardkonforme Implementierung zulaesst, ist die Annahme in C wuerde
Zweierkomplement verwendet *in* *dieser* *Allgemeinheit* *falsch*.
> aber das beschreibt nun mal die erdrückende Wahrheit,
Es ist im Kontext der Sprache C (also in brauchbaren Buechern ueber
die prache C und in dieser Gruppe) nicht "die Wahrheit" sondern schlicht
und ergreifend *FALSCH*.
> und daß es auch Ausnahmen {gegeben hat,gibt,geben kann}, ist doch
> noch lange kein Grund für den "totalen Verriß" eines C-Lehrbuchs!
Doch, ist es. Genauso wie die Verwendung system- oder implementierungs-
spezifischer Headerdateien und Futnkionen ohne auf die system- oder
implementierungs-spezifischen Dinge hinzuweisen ein Grund fuer einen
solchen Verriss waere (also z.B. "#include <conio.h>" oder dergleichen).
> Zumal jeder weiß, daß zur "Wahrheitsfindung" mindestens mal zwei
> Quellen (möglichst unabhängig voneinander) nötig sind, und sich
> "Wahrheiten" auch schon mal ändern können (-> Erdscheibe/-Kugel).
Durch unpassende Vergleiche werden deine Aussagen nicht richtiger.
> Claus Reibenstein wrote:
>
>> Michael Schumacher schrieb:
>>
>>> Juergen Ilse wrote:
>>>
>>>> Ein "unsigned char" ist in C der Datentyp, der genau ein (C-) Byte auf-
>>>> nehmen kann. Zumindest "unsigned char" und "byte" sind in C also nicht
>>>> so unterschiedlich wie du glaubst ...
>>>
>>> Äh, doch -- deshalb ja auch diese Diskussion! ;^)
Die Du angezettelt hast.
>> Dann erläutere doch bitte mal den Unterschied, den Du zu sehen glaubst,
>> und belege ihn anhand des C-Standards.
>
> C definiert sich sein eigenes "Byte" in Form eines "char";
Warum diskutieren wir hier dann eigentlich noch, wenn Du es weißt? Worüber?
> in der
> "restlichen" IT-Welt
Nochmal: Die restliche IT-Welt interessiert hier nicht. Hier geht es um
C und _nur_ um C.
> wird ein Byte (als Informationseinheit) als
> eine Folge von acht informationstragenden Bits beschrieben
Nochmal: Das meinte ich mit '"Byte" wird zwar in vielen Bereichen mit
"Oktett" gleichgesetzt' (<7jcaqmF...@mid.individual.net>,
<7jdu51F...@mid.individual.net>).
Vielleicht liest Du einfach mal den _ganzen_ Thread, bevor Du hier
weiter über Dinge diskutierst, die hier längst bekannt sind, aber
eigentlich niemanden interessieren.
Gruß. Claus
richtig.
> in der
> "restlichen" IT-Welt wird ein Byte (als Informationseinheit) als
> eine Folge von acht informationstragenden Bits beschrieben, die
> eine logische Einheit bilden.
Gerade in der IT-Welt nicht �berall. Dass ein Byte nicht immer 8 Bit
hat ist schliesslich keine Erfindung von C, diese Gleichsetzung mit
8 Bit kam erst im Lauf der Zeit und ist vor allem ausserhalb der
IT-Welt extrem vorherrschend.
Aber klar, ausserhalb von C sollte man extra dazusagen dass man mit
Byte nicht 8 Bit meint, wenn man verstanden werden will und von
C-Bytes spricht. Hier in einer C-Gruppe ist das nat�rlich nicht
n�tig, es geht schliesslich schon explizit um die Sprache C.
> Wenn Du wissen willst, wie "die Welt" au�erhalb von C ein Byte
> als Informationseinheit definiert,
[...]
Das h�ttest du dir sparen k�nnen, das ist hier durchaus bekannt.
> Nochmal: auch wenn der C-Standard seine eigene Vorstellung von
> einem Byte hat (was ja durchaus in Ordnung geht!), deckt sich
> diese nicht zwingend mit der g�ngigen Definition eines IT-Bytes:
Warum erfindest du eigene Begriffe? F�r das was du mit "IT-Byte"
meinst gibt es den eingef�hrten Begriff eines "Oktett". Nicht umsonst
wird der meist auch in Standards verwendet, da er Verwechslungen
mit anderen Definitionen von Bytes ausschliesst.
> eine tats�chliche C-Implementierung k�nnte selbst auf einem x86
> den Typ "char" (mit sizeof(char, int, long) = 1) als 32- oder
> gar 64-bit-Wort implementieren, und w�rde damit perfekt g�ltigen
> -- vermutlich sogar recht flotten! -- Code produzieren.
Genau darum gehts ja die ganze Zeit. In so einer Implementierung
w�r dann ein Byte halt 64 Bit gro�.
> Dann
> entspr�che eben ein "C-Byte" vier oder acht Bytes, und zwar
> *ungeachtet dessen*, ob die x86-Architektur tats�chlich auch
> einzelne Bytes (zu jeweils acht Bits) adressieren kann -- und
> das ist eben der von mir erw�nhte Unterschied zwischen C-"char"s
> und IT-Bytes.
Nenn das ganze einfach Oktett, dann wirst auch verstanden und du
vermeidest Misverst�ndnisse.
> Es mag nicht 100%-ig korrekt sein, C-"int"s mit zwei gekoppelten
> IT-Bytes zu assoziieren, oder von einer CPU mit Zweierkomplement
> auszugehen, aber das beschreibt nun mal die erdr�ckende Wahrheit,
Aber wirklich nicht. Erstmal ist die Wahrheit eine andere, und
dass ein int 2 Oktetts braucht wird von Ottonormalanf�nger
wohl mittlerweile schon als exotisches System eingeordnet, der
"Normalfall" ist ein anderer.
> und da� es auch Ausnahmen {gegeben hat,gibt,geben kann}, ist doch
> noch lange kein Grund f�r den "totalen Verri�" eines C-Lehrbuchs!
Also wenn in einem C-Lehrbuch schon die Grundbegriffe falsch
verwendet werden, dann ist das eigentlich Grund genug f�r
einen Verri�.
> Ein C-Lehrbuch dass die Grundbegriffe von C falsch
> Zumal jeder wei�, da� zur "Wahrheitsfindung" mindestens mal zwei
> Quellen (m�glichst unabh�ngig voneinander) n�tig sind, und sich
> "Wahrheiten" auch schon mal �ndern k�nnen (-> Erdscheibe/-Kugel).
Ja und? Wenn im C19-Standard (oder was weiss ich wenn sich die
Wahrheit in C im Sinn eines neuen Standards �ndert) ein Byte zu einem
Oktett umdefiniert wird, dann wird man die Kritik halt �berarbeiten.
Ist ja mit den //-Kommentaren auch nicht anders, die fr�her als
C++ Kommentare verrissen wurden, und mittlerweile aber auch in C
Eingang gefunden haben. (Allerdings glaub ich nicht daran, dass
in C ein Byte mal anders definiert werden wird, dazu gibt es eigentlich
keinen Grund).
Tom
Thomas Koller schrieb:
[..]
> Ja und? Wenn im C19-Standard (oder was weiss ich wenn sich die
> Wahrheit in C im Sinn eines neuen Standards �ndert) ein Byte zu einem
> Oktett umdefiniert wird, dann wird man die Kritik halt �berarbeiten.
> Ist ja mit den //-Kommentaren auch nicht anders, die fr�her als
> C++ Kommentare verrissen wurden, und mittlerweile aber auch in C
> Eingang gefunden haben. (Allerdings glaub ich nicht daran, dass
> in C ein Byte mal anders definiert werden wird, dazu gibt es eigentlich
> keinen Grund).
Nun wird mir wieder einmal in aller Deutlichkeit klar,
dass nicht nur das C-Compilat systemabh�ngig ist,
sondern auch der Quellcode an sich.
Da es gen�gend Menschen gibt, die schon immer Delfin mit f
geschrieben haben wurde die fr�here korrekte Schreibweise mit ph eben
falsch. So �hnlich kann sich auch das Byte in 8bit verwandeln.
Es w�rde zwar nichts im Sinne von systemunabh�ngigem Compilat bringen,
aber doch einen deutlichen Schritt in bessere Portierbarkeit des
Quellcodes denn:
Wenn das System kein Oktett adressieren kann, dann kann es das nicht.
Aber was oder wer sollte einen C-Compiler bei Systemen, die keine
Oktetts adressieren k�nnen, daran hindern Daten, die in ein Oktett
passen, entweder in dem einen Fall in einer gr��eren systemspezifischen
Einheit oder in dem anderen Fall auf zwei (oder gar mehrere)
systemspezifischen Einheiten abzulegen, solange auf der C Ebene
system�bergreifend einheitliche Gr��en der Datentypen existieren?
Gru� Robert
P.S. Auch w�re ein standardisierte Unterst�tzung von Hard- und
Softwareinterrupts w�nschenswert. Ist das evtl schon in der Mache?
Robert Hartmann <Robert_...@gmx.net> wrote:
> Nun wird mir wieder einmal in aller Deutlichkeit klar,
> dass nicht nur das C-Compilat systemabhängig ist,
> sondern auch der Quellcode an sich.
Wenn der Source System- oder Compiler-abhaengig geschrieben wurde: ja.
Das ist aber nicht wirklich ueberraschend. Man kann natuerlich auch
System- und Compiler-unabhaengigen Code verfassen, der keine Eigen-
schaften vorraussetzt, die vom Standard nicht zugesagt werden. Damit
duerfte man dann sehr viel portabler sein ...
> Es würde zwar nichts im Sinne von systemunabhängigem Compilat bringen,
> aber doch einen deutlichen Schritt in bessere Portierbarkeit des
> Quellcodes denn:
> Wenn das System kein Oktett adressieren kann, dann kann es das nicht.
> Aber was oder wer sollte einen C-Compiler bei Systemen, die keine
> Oktetts adressieren können, daran hindern Daten, die in ein Oktett
> passen, entweder in dem einen Fall in einer größeren systemspezifischen
> Einheit oder in dem anderen Fall auf zwei (oder gar mehrere)
> systemspezifischen Einheiten abzulegen, solange auf der C Ebene
> systemübergreifend einheitliche Größen der Datentypen existieren?
Das wird auch durchaus so gemacht. Da aber der Datentyp "unsigned char"
weder padding- noch parity-Bits enthalten darf und den Wert in "pure
binary representation" darzustellen hat, ist in einem solchen Fall dann
eben CHAR_BIT groesser als 8 und ein Byte (im Sinne von C) eben *kein*
Oktett. Darum dreht sich ja diese Diskussion.
Wenn du nicht rein in Standard-C programmierst (und das machen
vermutlich die meisten nicht), dann ist der Quellcode nat�rlich
systemabh�ngig. Wird hier ja die ganze Zeit gepredigt. :-)
Wobei dann die systemabh�ngigen Teile hier off-topic sind. (Die
Diskussion _ob_ es systemabh�ngig ist, ist nat�rlich on-topic).
> Da es gen�gend Menschen gibt, die schon immer Delfin mit f
> geschrieben haben wurde die fr�here korrekte Schreibweise mit ph eben
> falsch. So �hnlich kann sich auch das Byte in 8bit verwandeln.
Bl�des Beispiel. Delphin ist nach der aktuellen Rechtschreibung nicht
falsch. ;-) Das bessere Beispiel ist hier eher der // Kommentar, der
fr�her in C falsch war, jetzt aber nicht mehr.
> Es w�rde zwar nichts im Sinne von systemunabh�ngigem Compilat bringen,
> aber doch einen deutlichen Schritt in bessere Portierbarkeit des
> Quellcodes denn:
>
> Wenn das System kein Oktett adressieren kann, dann kann es das nicht.
Ja und? In C ist das eh einfach, da du hier ein Byte nicht auf ein
Oktett begrenzt hast, die "Einheit" kann durchaus auch 32 Bit sein,
und ist es auch auf manchen Systemen.
Bei Sprachen die 8Bit daf�r verlangen muss dann halt der Compiler
ausmaskieren und die Hardwarerealit�t vor der Implementierung verbergen.
> Aber was oder wer sollte einen C-Compiler bei Systemen, die keine
> Oktetts adressieren k�nnen, daran hindern Daten, die in ein Oktett
> passen, entweder in dem einen Fall in einer gr��eren systemspezifischen
> Einheit oder in dem anderen Fall auf zwei (oder gar mehrere)
> systemspezifischen Einheiten abzulegen,
Nichts. Wieso kommst du auf die Idee etwas w�rde so einen Compiler
verhindern?
> solange auf der C Ebene
> system�bergreifend einheitliche Gr��en der Datentypen existieren?
In C gibts aber keine solchen einheitlichen Gr��en der Datentypen
wie in anderen Sprachen. Bzw., f�r jemand der sowas braucht gibt es
die intN_t Typen, um einheitliche Namen verwenden zu k�nnen. Dann
siehst gleich beim kompilieren, wenn's einen von dir ben�tigten Typ
nicht gibt und du kannst dir bei Bedarf einen anderen Compiler suchen.
Tom
> Nun wird mir wieder einmal in aller Deutlichkeit klar,
> dass nicht nur das C-Compilat systemabh�ngig ist,
> sondern auch der Quellcode an sich.
Es gibt reichlich Probleme, die nichts mit der darunter liegenden
Hardware zu tun haben. Diese lassen sich idR in C auch systemunabh�ngig
formulieren. Insofern ist Deine Aussage Unsinn.
> Da es gen�gend Menschen gibt, die schon immer Delfin mit f
> geschrieben haben wurde die fr�here korrekte Schreibweise mit ph eben
> falsch. So �hnlich kann sich auch das Byte in 8bit verwandeln.
Oder die von Kompression sprechen, wenn eigentlich Reduktion gemeint
ist. Oder die Internet sagen, aber WWW meinen. Oder Usenet-Gruppen als
Foren bezeichnen. Oder ... oder ... oder ...
Hier geht es allerdings um den Begriff Byte - und der ist im Standard
eindeutig definiert.
> Es w�rde zwar nichts im Sinne von systemunabh�ngigem Compilat bringen,
> aber doch einen deutlichen Schritt in bessere Portierbarkeit des
> Quellcodes denn:
Die Portierbarkeit hat weniger mit der Sprache zu tun, sondern eher mit
den F�higkeiten und dem Willen der Entwickler.
100-prozentige Portierbarkeit wird es sowieso nie geben. Nicht mal in
Java ist diese gegeben.
> Wenn das System kein Oktett adressieren kann, dann kann es das nicht.
Richtig. Ist hier aber nicht relevant. Es ist nirgends vorgeschrieben,
dass die Adressierung in C irgendetwas mit der Adressierung der
darunterliegenden Hardware zu tun haben muss.
> Aber was oder wer sollte einen C-Compiler bei Systemen, die keine
> Oktetts adressieren k�nnen, daran hindern Daten, die in ein Oktett
> passen, entweder in dem einen Fall in einer gr��eren systemspezifischen
> Einheit oder in dem anderen Fall auf zwei (oder gar mehrere)
> systemspezifischen Einheiten abzulegen,
Was beides in der Praxis auch passiert, allerdings unter eventueller
Anpassung der Bytegr��e und/oder der Adressierung.
Ebenso k�nnte der C-Compiler die Daten auch einfach als Oktett (oder
sonst einer hardwareunabh�ngigen Einheit) speichern.
> solange auf der C Ebene
> system�bergreifend einheitliche Gr��en der Datentypen existieren?
Solche Datentypen existieren, und zwar sowohl als Datentypen fester
Gr��e (die allerdings nicht �berall existieren m�ssen) als auch mit
definierter Mindestgr��e (die �berall existieren m�ssen). Wer also
bestimmte Mindestgr��en ben�tigt oder haben m�chte, braucht nur die
entsprechenden Datentypen zu benutzen, um portabel zu bleiben.
Bei den Datentypen fester Gr��e kann es allerdings zu einem
Compilerfehler kommen. Immerhin erf�hrt man so fr�hzeitig, wo man
anpassen muss, und merkt nicht erst an falschen Ergebnissen (deren
Ursache schwer zu finden ist) oder sporadischem Fehlverhalten (dessen
Ursache noch schwerer zu finden ist), dass irgendetwas nicht stimmt.
> P.S. Auch w�re ein standardisierte Unterst�tzung von Hard- und
> Softwareinterrupts w�nschenswert. Ist das evtl schon in der Mache?
Hardware-Interrupts sind - wie der Name schon sagt - hardwarespezifisch.
Eine portable Unterst�tzung derselben kann es schon aus Prinzip nicht geben.
Gru�. Claus
>> Bei UTF8 geht man ja tats�chlich von Folgen von 8-Bit aus.
>
> Deswegen hei�t es ja UTF-8. Hat man nur 7 Bit, nimmt man UTF-7. Hat man
> 9 Bit, nimmt man UTF-9. Hat man 16 Bit, nimmt man UTF-16.
Das halte ich f�r ein Ger�cht. Die Kodierungen haben noch weitere
Eigensch�ften, die sie unterscheiden.
> Du kannst int8_t & Co. aus <stdint.h> benutzen. Damit wird dein Programm
> eben nur auf Maschinen kompilieren, die 8-bit-Typen haben, dort wird es
> aber das gew�nschte Verhalten zeigen.
Wirklich? int8_t kann immer durch signed char ersetzt werden.
> Das ist aber gerade der relevante Punkt: Nicht 1000 lineare "char"s zu je
> acht Bit, sondern 1000 lineare "char"s (*ohne* die nicht zwingend zutref-
> fende Groessenangabe). Es gibt C-Implementierungen, bei denen ein char eben
> *nicht* 8 Bit breit ist (sondern 16, 24 oder gar 32 Bit).
Welche denn?
Au�erdem verstehe ich nicht, warum C noch immer diesen Aufwand
treibt. Das mag auch daran liegen, da� die obskure Architektur, die
ich hier noch herumfahren habe, 4 Bit gro�e Bytes hat und W�rter aus 5
Bytes. Daf�r reichen die C-Freir�ume immer noch nicht aus.
Inzwischen schafft POSIX den Schabernack gl�cklicherweise ab.
> * Stefan Reuther:
>
>> Deswegen hei�t es ja UTF-8. Hat man nur 7 Bit, nimmt man UTF-7. Hat man
>> 9 Bit, nimmt man UTF-9. Hat man 16 Bit, nimmt man UTF-16.
>
> Das halte ich f�r ein Ger�cht. Die Kodierungen haben noch weitere
> Eigensch�ften, die sie unterscheiden.
Wobei mir UTF-9 bislang unbekannt war. Ich glaube auch nicht, dass sich
das durchsetzen wird (ebensowenig wie UTF_18). Schlie�lich basieren die
Bytegr��en der meisten Architekturen auf 2er-Potenzen, und der gro�e
Vorteil von UTF-8 ist seine Abw�rts-Kompatibilit�t mit ASCII.
Das ist aber ein ganz anderes Thema und hat nichts mit C zu tun.
>> Du kannst int8_t & Co. aus <stdint.h> benutzen. Damit wird dein Programm
>> eben nur auf Maschinen kompilieren, die 8-bit-Typen haben, dort wird es
>> aber das gew�nschte Verhalten zeigen.
>
> Wirklich? int8_t kann immer durch signed char ersetzt werden.
Nein!
Programme, die einen 8-Bit-Datentyp ben�tigen und daf�r (u)int8_t
verwenden, lassen sich auf einer Maschine mit char > 8 Bit nicht
�bersetzen. Programme, die statt dessen (un)signed char benutzen, werden
auf solchen Maschinen problemlos �bersetzt und ausgef�hrt, liefern aber
falsche Ergebnisse.
Gru�. Claus
> * Juergen Ilse:
>
>> Das ist aber gerade der relevante Punkt: Nicht 1000 lineare "char"s zu je
>> acht Bit, sondern 1000 lineare "char"s (*ohne* die nicht zwingend zutref-
>> fende Groessenangabe). Es gibt C-Implementierungen, bei denen ein char eben
>> *nicht* 8 Bit breit ist (sondern 16, 24 oder gar 32 Bit).
>
> Welche denn?
Es wurden hier schon mehrfach welche genannt. Habe aber gerade keine
Lust, selber nachzuschauen :-)
> Au�erdem verstehe ich nicht, warum C noch immer diesen Aufwand
> treibt. Das mag auch daran liegen, da� die obskure Architektur, die
> ich hier noch herumfahren habe, 4 Bit gro�e Bytes hat und W�rter aus 5
> Bytes. Daf�r reichen die C-Freir�ume immer noch nicht aus.
Welcher "Aufwand"? Welche "C-Freir�ume"? Wovon sprichst Du?
Nat�rlich kann man auch f�r solch eine Architektur einen
standardkonformen C-Compiler bauen. Ein int h�tte dort sinnvollerweise
20 Bit, ein char somit entweder 10 Bit (halbes Maschinenwort) oder
ebenfalls 20 Bit. Oder man ignoriert das Maschinenwort und legt int mit
16 und char mit 8 Bit fest (also 4 bzw. 2 Maschinenbytes).
Zus�tzlich k�nnte man den C-Compiler f�r diese Architektur um einen
Typen (u)int4_t erweitern, um auch einzelne Maschinenbytes ansprechen zu
k�nnen.
Wo ist das Problem?
> Inzwischen schafft POSIX den Schabernack gl�cklicherweise ab.
Welchen "Schabernack"?
Gru�. Claus
Florian Weimer <f...@deneb.enyo.de> wrote:
> * Juergen Ilse:
>> Das ist aber gerade der relevante Punkt: Nicht 1000 lineare "char"s zu je
>> acht Bit, sondern 1000 lineare "char"s (*ohne* die nicht zwingend zutref-
>> fende Groessenangabe). Es gibt C-Implementierungen, bei denen ein char eben
>> *nicht* 8 Bit breit ist (sondern 16, 24 oder gar 32 Bit).
> Welche denn?
IIRC gab es da z.B. einen C-Compiler fuer die TMS32000 CPU-Serie.
Bei dem waren sowohl char als auch short, int und long jeweils 32 Bit
breit (sowohl signed als auch unsigned). Es duerfte aber noch mehr
gegeben haben ...
> Außerdem verstehe ich nicht, warum C noch immer diesen Aufwand
> treibt. Das mag auch daran liegen, daß die obskure Architektur, die
> ich hier noch herumfahren habe, 4 Bit große Bytes hat und Wörter aus 5
> Bytes. Dafür reichen die C-Freiräume immer noch nicht aus.
Der C-Standard fordert als Mindestgroesse fuer ein Byte 8 Bit, also
sind 4-Bit-Bytes in einer standardkonformen Implementierung nicht
moeglich.
Florian Weimer <f...@deneb.enyo.de> wrote:
> * Stefan Reuther:
>> Du kannst int8_t & Co. aus <stdint.h> benutzen. Damit wird dein Programm
>> eben nur auf Maschinen kompilieren, die 8-bit-Typen haben, dort wird es
>> aber das gewünschte Verhalten zeigen.
> Wirklich? int8_t kann immer durch signed char ersetzt werden.
Nicht ohne bei manchen Implementierungen die Semantik zu aendern ...
Allerdings ist es nicht unwahrscheinlich, dass man dann bei diesen
Implementierungen eine Fehlermeldung erhalten wuerde, weil "int8_t"
nicht existiert (es dort also keinen genau 8 Bit breiten Ganzzahl-
Typ gibt ...). Die Fehlermeldung beim compilieren erscheint mir aber
gegenueber "keinerlei Fehlermeldung aber nicht funktionierendes
Programm" die sinnvollere Alternative ...
Wir sprechen hier aber von einem C-Compiler. Und der legt als
Mindestgr��e 8 Bit f�r ein Byte, und damit auch f�r ein Objekt,
fest. Oder wenn du in deiner Implementierung ein char mit 10 Bit
ansetzt, dann w�re der minimale Typ auch int10_t.
Wenn du auf Bitebene weiter runtergehen willst, m�sstest mit Bitfeldern
arbeiten, wobei aber ein einzelnes Objekt (also z.b. eine Variable)
trotzdem immer nur eine ganzzahlige Gr��e an Bytes braucht.
Oder mit anderen Worten, du kannst dir zwar einen Compiler bauen
der einen Typen int4_t unterst�tzt, aber das w�re dann kein
standardkonformer C-Compiler, sondern eine spezifische Erweiterung f�r
diese spezielle Architektur.
Tom
> Claus Reibenstein <4spame...@online.de> wrote:
>
>> Nat�rlich kann man auch f�r solch eine Architektur einen
>> standardkonformen C-Compiler bauen. [...]
>>
>> Zus�tzlich k�nnte man den C-Compiler f�r diese Architektur um einen
>> Typen (u)int4_t erweitern, um auch einzelne Maschinenbytes ansprechen zu
>> k�nnen.
>
> Wir sprechen hier aber von einem C-Compiler. Und der legt als
> Mindestgr��e 8 Bit f�r ein Byte, und damit auch f�r ein Objekt,
> fest. Oder wenn du in deiner Implementierung ein char mit 10 Bit
> ansetzt, dann w�re der minimale Typ auch int10_t.
Wie kommst Du auf dieses schmale Brett?
Ich habe schon mit Architekturen gearbeitet (ist noch gar nicht so lange
her), die es erm�glichte, in bestimmten Bereichen einzelne Bits zu
adressieren. Der zugeh�rige C-Compiler unterst�tzte dies, indem er einen
Datentyp "bit" zur Verf�gung stellte.
Dass dies - ebenso wie mein vorgeschlagener (u)int4_t - eine Erweiterung
gegen�ber dem Standard darstellt, ist klar. Der Standard verbietet
solche Erweiterungen aber nicht.
> Wenn du auf Bitebene weiter runtergehen willst, m�sstest mit Bitfeldern
> arbeiten, wobei aber ein einzelnes Objekt (also z.b. eine Variable)
> trotzdem immer nur eine ganzzahlige Gr��e an Bytes braucht.
Wenn ich standardkonform programmmieren will: Ja.
> Oder mit anderen Worten, du kannst dir zwar einen Compiler bauen
> der einen Typen int4_t unterst�tzt, aber das w�re dann kein
> standardkonformer C-Compiler, sondern eine spezifische Erweiterung f�r
> diese spezielle Architektur.
Der C-Compiler kann sehr wohl standardkonform sein. Standardkonform
hei�t ja nicht, dass er keine zus�tzlichen Features unterst�tzen darf,
sondern dass er das, was der Standard fordert, vollst�ndig abdecken muss.
Programme, die diese zus�tzlichen Features nutzen, sind nat�rlich nicht
mehr standardkonform.
Gru�. Claus
Florian Weimer wrote:
> * Juergen Ilse:
>>Das ist aber gerade der relevante Punkt: Nicht 1000 lineare "char"s zu je
>>acht Bit, sondern 1000 lineare "char"s (*ohne* die nicht zwingend zutref-
>>fende Groessenangabe). Es gibt C-Implementierungen, bei denen ein char eben
>>*nicht* 8 Bit breit ist (sondern 16, 24 oder gar 32 Bit).
>
> Welche denn?
Pers�nlich kenne ich den Motorola 56000, und dann gibt's da wohl auch
noch was aus der TMS320'er-Serie.
> Au�erdem verstehe ich nicht, warum C noch immer diesen Aufwand
> treibt. Das mag auch daran liegen, da� die obskure Architektur, die
> ich hier noch herumfahren habe, 4 Bit gro�e Bytes hat und W�rter aus 5
> Bytes. Daf�r reichen die C-Freir�ume immer noch nicht aus.
HP Saturn? Ich hab das Ding nicht ausprobiert, aber wenn ich das richtig
gelesen habe, bestehen da die *Adressen* aus 5 Nibbles, nicht die
Integer. Ein C-Compiler k�nnte zum Beispiel immer zwei Nibbles zusammen-
fassen, sizeof(void*) w�re 3. Er k�nnte dann aber nicht alles adressieren,
was in Assembler adressierbar ist. Das w�re jetzt nicht tragisch, das
gilt f�r x86 auch (MS-DOS "tiny" model kann halt mit "far"-Zeigern
nichts anfangen).
> Inzwischen schafft POSIX den Schabernack gl�cklicherweise ab.
Aber auch POSIX macht erstmal keine Vorschriften f�r sizeof(long). Warum
auch? Ich bin immer noch der Meinung, dass man das als Einsteiger nicht
wissen muss. Und dabei ist v�llig egal, ob man das nicht wissen muss,
weil die Anzahl oder die Gr��e der Bytes pro long implementation-defined
ist.
Stefan
UTF-9 ist jetzt nicht so klever entworfen wie UTF-8, aber bei einem RFC
mit diesem Publikationsdatum w�re ich da nicht so streng :-)
>>Du kannst int8_t & Co. aus <stdint.h> benutzen. Damit wird dein Programm
>>eben nur auf Maschinen kompilieren, die 8-bit-Typen haben, dort wird es
>>aber das gew�nschte Verhalten zeigen.
>
> Wirklich? int8_t kann immer durch signed char ersetzt werden.
Nicht immer. 'int8_t' kann, sofern er existiert, den Wert -128
aufnehmen, 'signed char' nicht unbedingt. In jedem Fall kann man 'i+128'
sicher als Index in ein Array mit 256 Elementen nehmen, wenn 'i' den Typ
'int8_t' hat, nicht jedoch bei 'signed char'.
Das �berlaufverhalten ist bei beiden gleich undefiniert, aber dann nimmt
man eben 'uint8_t', der garantiert mod 256 rechnet.
Stefan
Indem ich den Standard lese.
> Ich habe schon mit Architekturen gearbeitet (ist noch gar nicht so lange
> her), die es erm�glichte, in bestimmten Bereichen einzelne Bits zu
> adressieren. Der zugeh�rige C-Compiler unterst�tzte dies, indem er einen
> Datentyp "bit" zur Verf�gung stellte.
Das ist dann aber nicht Standard-C, darum geht's ja.
>
> Dass dies - ebenso wie mein vorgeschlagener (u)int4_t - eine Erweiterung
> gegen�ber dem Standard darstellt, ist klar. Der Standard verbietet
> solche Erweiterungen aber nicht.
Der Standard definiert was intN_t zu sein hat. Wenn bei deinem
Compiler intN_t was anderes ist, dann ist das nicht mehr Standard-C.
Tom
> Claus Reibenstein <4spame...@online.de> wrote:
>
>> Thomas Koller schrieb:
>>
>>> Claus Reibenstein <4spame...@online.de> wrote:
>>>
>>>> Nat�rlich kann man auch f�r solch eine Architektur einen
>>>> standardkonformen C-Compiler bauen. [...]
>>>> Zus�tzlich k�nnte man den C-Compiler f�r diese Architektur um einen
>>>> Typen (u)int4_t erweitern, um auch einzelne Maschinenbytes ansprechen zu
>>>> k�nnen.
>>>
>>> Wir sprechen hier aber von einem C-Compiler. Und der legt als
>>> Mindestgr��e 8 Bit f�r ein Byte, und damit auch f�r ein Objekt,
>>> fest. Oder wenn du in deiner Implementierung ein char mit 10 Bit
>>> ansetzt, dann w�re der minimale Typ auch int10_t.
>>
>> Wie kommst Du auf dieses schmale Brett?
>
> Indem ich den Standard lese.
Welche Stelle genau hat Dich auf dieses schmale Brett gef�hrt und warum?
>> Ich habe schon mit Architekturen gearbeitet (ist noch gar nicht so lange
>> her), die es erm�glichte, in bestimmten Bereichen einzelne Bits zu
>> adressieren. Der zugeh�rige C-Compiler unterst�tzte dies, indem er einen
>> Datentyp "bit" zur Verf�gung stellte.
>
> Das ist dann aber nicht Standard-C, darum geht's ja.
Wo habe ich behauptet, dass diese Erweiterungen Standard-C seien? Dass
sie es nicht sind, wei� ich (ergibt sich eigentlich schon aus dem
Kontext), und wenn Du den n�chsten Abschnitt, in dem ich das noch einmal
klargestellt habe, nicht nur zitiert, sondern auch gelesen h�ttest,
h�ttest Du das erkannt:
>> Dass dies - ebenso wie mein vorgeschlagener (u)int4_t - eine Erweiterung
>> gegen�ber dem Standard darstellt, ist klar. Der Standard verbietet
>> solche Erweiterungen aber nicht.
N�chstes Mal also bitte _erst_ lesen _und_ verstehen und _dann_
vielleicht antworten.
> Der Standard definiert was intN_t zu sein hat. Wenn bei deinem
> Compiler intN_t was anderes ist, dann ist das nicht mehr Standard-C.
In "meinem" Compiler bezeichnen int4_t und uint4_t jeweils einen 4 Bit
breiten Datentyp (was sonst?) und entsprechen somit exakt dem, was der
Standard in 7.18.1.1 "Exact-width integer types" �ber diese Typen aussagt:
,----------
| 1 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.
|
| 2 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.
|
| 3 These types are optional. However, if an implementation provides
| integer types with widths of 8, 16, 32, or 64 bits, no padding bits,
| and (for the signed types) that have a two�s complement
| representation, it shall define the corresponding typedef names.
`----------
Gru�. Claus
> Thomas Koller schrieb:
>
>> Claus Reibenstein <4spame...@online.de> wrote:
>>
>>> Thomas Koller schrieb:
>>>
>>>> Wir sprechen hier aber von einem C-Compiler. Und der legt als
>>>> Mindestgr��e 8 Bit f�r ein Byte, und damit auch f�r ein Objekt,
>>>> fest. Oder wenn du in deiner Implementierung ein char mit 10 Bit
>>>> ansetzt, dann w�re der minimale Typ auch int10_t.
>>>
>>> Wie kommst Du auf dieses schmale Brett?
>>
>> Indem ich den Standard lese.
>
> Welche Stelle genau hat Dich auf dieses schmale Brett gef�hrt und
> warum?
Vielleicht:
6.2.6.1p2:
Except for bit-fields, objects are composed of contiguous sequences
of one or more bytes [...]
>>> Ich habe schon mit Architekturen gearbeitet (ist noch gar nicht so
>>> lange her), die es erm�glichte, in bestimmten Bereichen einzelne
>>> Bits zu adressieren. Der zugeh�rige C-Compiler unterst�tzte dies,
>>> indem er einen Datentyp "bit" zur Verf�gung stellte.
>>
>> Das ist dann aber nicht Standard-C, darum geht's ja.
>
> Wo habe ich behauptet, dass diese Erweiterungen Standard-C seien? Dass
> sie es nicht sind, wei� ich (ergibt sich eigentlich schon aus dem
> Kontext), und wenn Du den n�chsten Abschnitt, in dem ich das noch
> einmal klargestellt habe, nicht nur zitiert, sondern auch gelesen
> h�ttest, h�ttest Du das erkannt:
>
>>> Dass dies - ebenso wie mein vorgeschlagener (u)int4_t - eine
>>> Erweiterung gegen�ber dem Standard darstellt, ist klar. Der Standard
>>> verbietet solche Erweiterungen aber nicht.
>
> N�chstes Mal also bitte _erst_ lesen _und_ verstehen und _dann_
> vielleicht antworten.
>
>> Der Standard definiert was intN_t zu sein hat. Wenn bei deinem
>> Compiler intN_t was anderes ist, dann ist das nicht mehr Standard-C.
>
> In "meinem" Compiler bezeichnen int4_t und uint4_t jeweils einen 4 Bit
> breiten Datentyp (was sonst?) und entsprechen somit exakt dem, was der
> Standard in 7.18.1.1 "Exact-width integer types" �ber diese Typen
> aussagt:
Schon. Aber was w�re denn dann sizeof(int4_t[3])?
-- Ralf
> Claus Reibenstein wrote:
>
>> Welche Stelle genau hat Dich auf dieses schmale Brett gef�hrt und
>> warum?
>
> Vielleicht:
>
> 6.2.6.1p2:
> Except for bit-fields, objects are composed of contiguous sequences
> of one or more bytes [...]
Dies gilt f�r die Standard-Typen. F�r implementationsspezifische Typen
muss das nicht gelten.
>> In "meinem" Compiler bezeichnen int4_t und uint4_t jeweils einen 4 Bit
>> breiten Datentyp (was sonst?) und entsprechen somit exakt dem, was der
>> Standard in 7.18.1.1 "Exact-width integer types" �ber diese Typen
>> aussagt:
>
> Schon. Aber was w�re denn dann sizeof(int4_t[3])?
sizeof ist auf diesen Typ nicht anwendbar.
Gru�. Claus
Dass Objekte in C nur Vielfache von Bytes gro� sein k�nnen?
Das steht in 6.2.6.1
>>> Ich habe schon mit Architekturen gearbeitet (ist noch gar nicht so lange
>>> her), die es erm�glichte, in bestimmten Bereichen einzelne Bits zu
>>> adressieren. Der zugeh�rige C-Compiler unterst�tzte dies, indem er einen
>>> Datentyp "bit" zur Verf�gung stellte.
>>
>> Das ist dann aber nicht Standard-C, darum geht's ja.
>
> Wo habe ich behauptet, dass diese Erweiterungen Standard-C seien? Dass
> sie es nicht sind, wei� ich (ergibt sich eigentlich schon aus dem
> Kontext), und wenn Du den n�chsten Abschnitt, in dem ich das noch einmal
> klargestellt habe, nicht nur zitiert, sondern auch gelesen h�ttest,
> h�ttest Du das erkannt:
Falls du es nicht bemerkt haben solltest, wie reden hier von C. Eine
Erweiterung mit Objekten wie von dir beschrieben w�re aber nicht
mehr C.
>> Der Standard definiert was intN_t zu sein hat. Wenn bei deinem
>> Compiler intN_t was anderes ist, dann ist das nicht mehr Standard-C.
>
> In "meinem" Compiler bezeichnen int4_t und uint4_t jeweils einen 4 Bit
> breiten Datentyp (was sonst?) und entsprechen somit exakt dem, was der
> Standard in 7.18.1.1 "Exact-width integer types" �ber diese Typen aussagt:
>
> ,----------
> | 1 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.
> |
> | 2 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.
> |
> | 3 These types are optional. However, if an implementation provides
> | integer types with widths of 8, 16, 32, or 64 bits, no padding bits,
> | and (for the signed types) that have a two???s complement
> | representation, it shall define the corresponding typedef names.
> `----------
Wenn sie das w�rden, m�sstest du 4 Bit gro�e Bytes haben, und die sind
in C nicht erlaubt.
Tom
> Falls du es nicht bemerkt haben solltest, wie reden hier von C. Eine
> Erweiterung mit Objekten wie von dir beschrieben w�re aber nicht
> mehr C.
Falsch. _Du_ redest von C.
Ich habe aufgezeigt, dass man auf einer bestimmten Hardware mit
eigenartiger Architektur einen standardkonformen C-Compiler aufsetzen
kann. Bis dahin habe ich auch noch von C gesprochen.
Ferner habe ich - als Antwort auf Florians merkw�rdige Anmerkung mit den
"C-Freir�umen" - eine M�glichkeit aufgezeigt, den Compiler um
hardwarespezifische Elemente zu erweitern.
Ich habe _ausdr�cklich_ erw�hnt, dass diese Erweiterungen _nicht_
standardkonform sind - und genau das hast _Du_ nicht begriffen bzw.
_willst_ es nicht begreifen.
Ich sehe daher - mal wieder - keinen Sinn darin, mit Dir weiter �ber
dieses Thema zu diskutieren (wobei ich das, was Du machst, nur aus
reiner H�flichkeit "diskutieren" nenne). F�r mich ist hier EOD.
Gru�. Claus
Stefan Reuther schrub:
> Aber auch POSIX macht erstmal keine Vorschriften für
> sizeof(long). Warum auch? Ich bin immer noch der Meinung, dass
> man das als Einsteiger nicht wissen muss.
Nicht wissen muss? Wenn ich einen Array mit 100000 Elementen
anlege, dann muss ich sehr wohl wissen, welchen Datentyp ich
brauche, um den Index speichern zu können.
Ich empfinde nach wie vor die anfängliche Undefiniertheit der
Wertebereiche von Ganzzahldatentypen in C als einen peinlichen
Lapsus, der wohl nur politische Gründe gehabt haben kann.
CU Rollo
Wenn die Frage lautet, welchen Typ du brauchst, um 0..99999
darzustellen, dann ist die Antwort ganz einfach 'long' oder
'int_least32_t' oder was in der Gegend. Wenn die Frage lautet,
ob du ein Array mit 100000 Elementen haben darfst, so lautet
die Antwort "nicht portabel".
> Ich empfinde nach wie vor die anfängliche Undefiniertheit der
> Wertebereiche von Ganzzahldatentypen in C als einen peinlichen
> Lapsus, der wohl nur politische Gründe gehabt haben kann.
Der politische Grund ist schlicht die existierende Praxis - im
Gegensatz zu z.B. Java soll eben C möglichst direkt auf (hier
ggf. das Wort "damals" einfügen) übliche Hardware abgebildet werden
können.
Und wer exakte Bitbreiten braucht, kann ja <stdint.h> nehmen
und damit seine Annahmen gleich im Code dokumentieren.
Stefan
Roland Damm <rolan...@arcor.de> wrote:
> Stefan Reuther schrub:
>> Aber auch POSIX macht erstmal keine Vorschriften für
>> sizeof(long). Warum auch? Ich bin immer noch der Meinung, dass
>> man das als Einsteiger nicht wissen muss.
> Nicht wissen muss? Wenn ich einen Array mit 100000 Elementen
> anlege, dann muss ich sehr wohl wissen, welchen Datentyp ich
> brauche, um den Index speichern zu können.
int32_t sollte dafuer reichen.
> Ich empfinde nach wie vor die anfängliche Undefiniertheit der
> Wertebereiche von Ganzzahldatentypen in C als einen peinlichen
> Lapsus, der wohl nur politische Gründe gehabt haben kann.
Nein, er hat einfach den Grund, dass es sehr unterschiedliche Hardware
gibt, und man es ermoeglichen wollte, die Integer Datentypen "nah an der
Hardware" zu implementieren.
Nicht nur ich. Ein Blick auf den Gruppennamen sollte dich
darauf aufmerksam machen, dass C das Thema ist.
> Ich habe aufgezeigt, dass man auf einer bestimmten Hardware mit
> eigenartiger Architektur einen standardkonformen C-Compiler aufsetzen
> kann. Bis dahin habe ich auch noch von C gesprochen.
Soweit war es ja auch ok.
> Ferner habe ich - als Antwort auf Florians merkw�rdige Anmerkung mit den
> "C-Freir�umen" - eine M�glichkeit aufgezeigt, den Compiler um
> hardwarespezifische Elemente zu erweitern.
So ein Compiler w�re aber nicht standardkonform, da du in C
wohldefinierte Typen anders verwendest. (Und nein, der C-Standard
l�sst dir nicht den Freiraum zu entscheiden ob der sizeof Parameter
auf int4_t angewendet werden darf oder nicht. _Wenn_ ein Compiler
einen intN_t anbietet, dann darf er das nur so wie im Standard
beschrieben tun)
In der Praxis wird es sehr oft so gemacht, �ber entsprechende
Compilereinstellungen hat man dann entweder einen reinen C-Compiler,
und ansonsten, wenn man z.b. sowas wie dein int4_t verwenden will,
einen C-�hnlichen Compiler mit Erweiterungen.
Das kann man nat�rlich immer und mit jedem Compiler in jeder Sprache
machen.
> Ich habe _ausdr�cklich_ erw�hnt, dass diese Erweiterungen _nicht_
> standardkonform sind - und genau das hast _Du_ nicht begriffen bzw.
> _willst_ es nicht begreifen.
H�ttest du dann noch dazugesagt: Dann ist es halt kein C-Compiler,
w�r ich zufrieden gewesen. Aber da du wiederholt von "standardkonform"
gesprochen hast, kommt nat�rlich Widerspruch.
Ich find es auch eine schwache "Ausrede", dass man Einschr�nkungen
die einem der C Standard bietet ja problemlos umgehen kann, indem
man einen Compiler macht der halt nur so �hnlich wie C ist. Wozu br�uchte
ich dann noch einen Standard?
Tom
[...]
> Ich empfinde nach wie vor die anf�ngliche Undefiniertheit der
> Wertebereiche von Ganzzahldatentypen in C als einen peinlichen
> Lapsus, der wohl nur politische Gr�nde gehabt haben kann.
'Politische Gruende' insofern, als dass es C etwas laenger gibt, als
'ANSI/ISO'-C. Die urspruenglich UNIX(*)-Hardware waren
16-Bit-Minicomputer (PDP-11), bei denen 'int' und 'unsigned' eben
16-Bit-Zahlen waren. Zum Zeitpunkt der ersten C-Norm (1989) waren
'16-Bit-Computer' keineswegs obsolet sondern wohl eher die am
weitesten verbreitete Architekturengruppe ueberhaupt. Die
UNIX(*)-Version fuer 32-Bit-Systeme, beginnend mit 32V fuer VAX,
hatten stattdessen 32 Bit breite Basisdatentypen. C-Compiler gab es
(und gibt es wohl auch noch) auch fuer 8-Bit-Prozessoren. Nach
oberflaechlichen Internet-Recherchen nach zu urteilen werden auch
immer noch 36-Bit wortaddressierende Mainframes gebaut. 1989 waren
solche Systeme jedenfalls auch noch in groesserem Umfang in Benutzung.
Die haeufige Annahme, dass der Begriff 'Computer' 'schon immer' (oder
sogar bloss heute) mit 'Intel-basierender PC' identisch war, ruehrt
eher von einem Hang zur intensiven Nabelschau her als das sie etwas
mit der beobachtbaren Realitaet gemeinsam haette.
> Hallo,
>
> Florian Weimer <f...@deneb.enyo.de> wrote:
>> * Stefan Reuther:
>>> Du kannst int8_t & Co. aus <stdint.h> benutzen. Damit wird dein Programm
>>> eben nur auf Maschinen kompilieren, die 8-bit-Typen haben, dort wird es
>>> aber das gew�nschte Verhalten zeigen.
>> Wirklich? int8_t kann immer durch signed char ersetzt werden.
>
> Nicht ohne bei manchen Implementierungen die Semantik zu aendern ...
Welche w�re das denn?
> Allerdings ist es nicht unwahrscheinlich, dass man dann bei diesen
> Implementierungen eine Fehlermeldung erhalten wuerde, weil "int8_t"
> nicht existiert (es dort also keinen genau 8 Bit breiten Ganzzahl-
> Typ gibt ...).
Es ist nicht ganz einfach, ein konformes Programm zu schreiben,
welches das Fehlen von Padding-Bits bei int8_t feststellen kann.
> Hallo,
>
> Florian Weimer wrote:
>> * Juergen Ilse:
>>>Das ist aber gerade der relevante Punkt: Nicht 1000 lineare "char"s zu je
>>>acht Bit, sondern 1000 lineare "char"s (*ohne* die nicht zwingend zutref-
>>>fende Groessenangabe). Es gibt C-Implementierungen, bei denen ein char eben
>>>*nicht* 8 Bit breit ist (sondern 16, 24 oder gar 32 Bit).
>>
>> Welche denn?
>
> Pers�nlich kenne ich den Motorola 56000,
Bis wann war das so? 568xx hat jedenfals CHAR_BIT == 8, und im
"large"-Modell ist sizeof(void *) 4 und nicht 3, obwohl nur 24 Bit
signifikant sind.
>> Au�erdem verstehe ich nicht, warum C noch immer diesen Aufwand
>> treibt. Das mag auch daran liegen, da� die obskure Architektur, die
>> ich hier noch herumfahren habe, 4 Bit gro�e Bytes hat und W�rter aus 5
>> Bytes. Daf�r reichen die C-Freir�ume immer noch nicht aus.
>
> HP Saturn?
Genau.
> Ich hab das Ding nicht ausprobiert, aber wenn ich das richtig
> gelesen habe, bestehen da die *Adressen* aus 5 Nibbles, nicht die
> Integer.
Die CPU kann (vermutlich durch Mikrokode) auf Wortbreiten zwischen 1
und 16 Nibbles arbeiten. Das System verwendet durchaus
20-Bit-Ganzzahlen zur Speicherung von Daten.
>> Inzwischen schafft POSIX den Schabernack gl�cklicherweise ab.
>
> Aber auch POSIX macht erstmal keine Vorschriften f�r sizeof(long).
Nein, das ist auch egal. Problematisch ist vor allem sizeof(off_t),
weil eine recht verbreitete 32-Bit-Architektur partout noch 4
verwenden m�chte. Aber das ist ein anderes Thema.
> IIRC gab es da z.B. einen C-Compiler fuer die TMS32000 CPU-Serie.
F�r ISO C?
> Bei dem waren sowohl char als auch short, int und long jeweils 32 Bit
> breit (sowohl signed als auch unsigned). Es duerfte aber noch mehr
> gegeben haben ...
Bei den fr�hen Alpha-Crays war das auch so. Das waren aber keine
C-Compiler im engeren Sinn. Die Syntax war zwar C, aber der Rest eher
nicht.
>> Au�erdem verstehe ich nicht, warum C noch immer diesen Aufwand
>> treibt. Das mag auch daran liegen, da� die obskure Architektur, die
>> ich hier noch herumfahren habe, 4 Bit gro�e Bytes hat und W�rter aus 5
>> Bytes. Daf�r reichen die C-Freir�ume immer noch nicht aus.
>
> Der C-Standard fordert als Mindestgroesse fuer ein Byte 8 Bit, also
> sind 4-Bit-Bytes in einer standardkonformen Implementierung nicht
> moeglich.
Eben! Damit lohnt sich der ganze Quatsch mit CHAR_BIT != 8 nicht, weil
damit immer noch nicht alle irgend einmal existenten Architekturen
abgedeckt sind.
In der Praxis d�rfte bei ISO C nur noch CHAR_BIT == 8 vorkommen.
Rainer Weikusat schrub:
>> Ich empfinde nach wie vor die anfängliche Undefiniertheit der
>> Wertebereiche von Ganzzahldatentypen in C als einen peinlichen
>> Lapsus, der wohl nur politische Gründe gehabt haben kann.
>
> 'Politische Gruende' insofern, als dass es C etwas laenger
> gibt, als 'ANSI/ISO'-C. Die urspruenglich UNIX(*)-Hardware
> waren 16-Bit-Minicomputer (PDP-11), bei denen 'int' und
> 'unsigned' eben 16-Bit-Zahlen waren. Zum Zeitpunkt der ersten
> C-Norm (1989) waren '16-Bit-Computer' keineswegs obsolet
> sondern wohl eher die am weitesten verbreitete
> Architekturengruppe ueberhaupt. Die UNIX(*)-Version fuer
> 32-Bit-Systeme, beginnend mit 32V fuer VAX, hatten stattdessen
> 32 Bit breite Basisdatentypen. C-Compiler gab es (und gibt es
> wohl auch noch) auch fuer 8-Bit-Prozessoren. Nach
> oberflaechlichen Internet-Recherchen nach zu urteilen werden
> auch immer noch 36-Bit wortaddressierende Mainframes gebaut.
> 1989 waren solche Systeme jedenfalls auch noch in groesserem
> Umfang in Benutzung.
Und gerade wegen dieser Heterogenität wäre es IMO eher
naheliegend gewesen, sowas wir int_8 gleich von vornherein
einzuführen. Wenn es dann die Hardware nicht kann, weil sie nur
int_7 kennt, merkt man das beim compilieren sofort (Datentyp ist
nicht definiert) anstatt erst zur Laufzeit irgendwelche
komischen Fehler zu bekommen.
CU Rollo
Juergen Ilse schrub:
>> Ich empfinde nach wie vor die anfängliche Undefiniertheit der
>> Wertebereiche von Ganzzahldatentypen in C als einen peinlichen
>> Lapsus, der wohl nur politische Gründe gehabt haben kann.
>
> Nein, er hat einfach den Grund, dass es sehr unterschiedliche
> Hardware gibt, und man es ermoeglichen wollte, die Integer
> Datentypen "nah an der Hardware" zu implementieren.
Das halte ich für ein Scheinargument. Was nutzt es mit wenn ich
weiß, dass die Zielhardware einen int gut verarbeiten kann, wenn
ich gleichzeitig nicht weiß, wie lang ein int überhaupt ist und
demzufolge garnicht weiß, ob ich ihn für meinen Zweck gebrauchen
kann. In dem Fall muss ich mein Programm (die darin benutzten
Datentypen) ja doch auf die jeweilige Hardware anpassen.
CU Rollo
Stefan Reuther schrub:
> Der politische Grund ist schlicht die existierende Praxis - im
> Gegensatz zu z.B. Java soll eben C möglichst direkt auf (hier
> ggf. das Wort "damals" einfügen) übliche Hardware abgebildet
> werden können.
Ich nehme an, damals war portabilität garnicht so sehr gefordert.
> Und wer exakte Bitbreiten braucht, kann ja <stdint.h> nehmen
> und damit seine Annahmen gleich im Code dokumentieren.
Inzwischen ist das Problem gelöst, ja.
CU Rollo
C89 fᅵr den TMS320C3x/40. Ich arbeite regelmᅵᅵig damit.
> Bei den frᅵhen Alpha-Crays war das auch so. Das waren aber keine
> C-Compiler im engeren Sinn. Die Syntax war zwar C, aber der Rest eher
> nicht.
Der TMS Compiler ist konform zum alten Standard, hat aber nur 32-bit
Integer Datentypen. Float ist 32-bit, double ist 64 bittig im Speicher und
40 bittig in der CPU.
> Eben! Damit lohnt sich der ganze Quatsch mit CHAR_BIT != 8 nicht, weil
> damit immer noch nicht alle irgend einmal existenten Architekturen
> abgedeckt sind.
>
> In der Praxis dᅵrfte bei ISO C nur noch CHAR_BIT == 8 vorkommen.
Wie gesagt: Ich arbeite immer noch regelmᅵᅵig mit dem TMS Compiler. Kann
sein, dass in Deiner Praxis nur CHAR_BIT == 8 vorkommt, in meiner ist das
nicht so.
Gruᅵ
Uz
--
Ullrich von Bassewitz u...@spamtrap.musoftware.de
22:33:46 up 3 days, 2:53, 14 users, load average: 0.14, 0.19, 0.15
Florian Weimer <f...@deneb.enyo.de> wrote:
> * Juergen Ilse:
>> IIRC gab es da z.B. einen C-Compiler fuer die TMS32000 CPU-Serie.
> Für ISO C?
Meines Wissens nach ja.
> In der Praxis dürfte bei ISO C nur noch CHAR_BIT == 8 vorkommen.
Die Realitaet sieht anders aus (auch wenn deine Aussage fuer sehr viele
standardkonforme C-Implementierungen gelten duerfte, aber eben laengst
nicht fuer alle). Welchen Grund sollte es geben, CHAR_BIT == 8 voraus-
zusetzen, wenn man evt. auch ohne diese nicht zwingend zutreffende
Voraussetzung und dafuer portabel hinkommen kann?
Roland Damm <rolan...@arcor.de> wrote:
> Und gerade wegen dieser Heterogenität wäre es IMO eher
> naheliegend gewesen, sowas wir int_8 gleich von vornherein
> einzuführen. Wenn es dann die Hardware nicht kann, weil sie nur
> int_7 kennt, merkt man das beim compilieren sofort (Datentyp ist
> nicht definiert) anstatt erst zur Laufzeit irgendwelche
> komischen Fehler zu bekommen.
Man bekommt die Fehler zur Compile-Time, wenn es den Datentyp int8_t
bei der verwendeten Implementierung nicht gibt. Da ist bei C nichts mit
"Fehler erst zur Laufzeit" ...
Der 56000 hat meines Wissens immer nur 24-bit-weise adressierbaren
Speicher gehabt. Wenn ich das richtig sehe, hat der 56800 damit nicht
viel zu tun.
Ich kenn den 56k von einem IC mit "Orpheus-Kern", der mit Motorola-
Tools und bei Bedarf dem gcc56k programmiert wird. Letzterer macht
CHAR_BIT=24, und das ist auch die Wortbreite, wenn man Assembler macht.
Das hier d�rfte noch so ein DSP mit einem entsprechenden Kern sein:
<http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=DSP56362&nodeId=0127955654>
Wenn man mal ins Datenblatt schaut: die Speicher sind alle 24 Bit breit,
auch der externe Datenbus hat D0..D23.
Stefan
Schrieb ich ja schon nebenan: w�hrend 'int8_t' garantiert den
Wertebereich -128 .. +127 hat, kann 'signed char' einen kleineren oder
gr��eren Bereich haben. Beides kann zu Fehlern f�hren. Eine Routine
void scramble(T p[], size_t n) {
static const T map[256] = { ... };
for (size_t i = 0; i < n; ++n)
p[i] = map[p[i] + 128];
}
wird halt funktionieren, wenn T 'int8_t' ist, aber nicht, wenn T ein
24-bit-char ist.
Stefan
Zahlreiche Anwendungsfälle kommen ohne das Wissen der exakten Bitbreiten
aus. Ich nutze 'int' zum Beispiel im Wesentlichen als 'int_least16_t':
für Werte mit einem garantierten Wertebereich von +/- 32k, gerne auch
mehr. Würde ich eine Programmiersprache verwenden, die von mir verlangt,
eine exakte Bitbreite anzugeben, hätte ich die Wahl zwischen 'int16_t'
(auf i386 langsamer, Strafzyklen wegen Präfix) und 'int32_t' (auf 8086,
Mikrocontroller, etc. langsamer weil mehr Speicherzugriffe).
Stefan
Doch, natürlich. Das geht sogar soweit, dass Turbo C 2.0 für DOS
Unix-Headerfiles nachbaut, inklusive unter DOS so nutzloser Makros wie
'S_IFIFO' und so knifflig zu implementierender Syscalls wie 'exec'. In
der README steht dann noch, dass sie die Signal-Funktionen von Unix
System III nun rausgeworfen und durch die von System V bzw. ANSI-C
ersetzt haben.
>>Und wer exakte Bitbreiten braucht, kann ja <stdint.h> nehmen
>>und damit seine Annahmen gleich im Code dokumentieren.
>
> Inzwischen ist das Problem gelöst, ja.
<stdint.h> hätte man sich auch problemlos aus <limits.h> selbst
zusammenbauen können.
#if UCHAR_MAX == 255
typedef unsigned char uint8_t;
#endif
Stefan
Stefan Reuther <stefa...@arcor.de> wrote:
> Schrieb ich ja schon nebenan: während 'int8_t' garantiert den
> Wertebereich -128 .. +127 hat,
Da bei signerd Datentypen in C auch Einerkomplement-Darstellung moeglich
ist, kannst du dich bei int8_t nur auf den Wertebereich -127 ... +127
verlassen.
> kann 'signed char' einen kleineren oder
> größeren Bereich haben.
Einen kleineren nicht, denn fuer signed char ist der Mindestwertebereich
laut Standard -127 .. 127, weniger waere nicht mehr standardkonform.
Juergen Ilse schrub:
> Man bekommt die Fehler zur Compile-Time, wenn es den Datentyp
> int8_t bei der verwendeten Implementierung nicht gibt. Da ist
> bei C nichts mit "Fehler erst zur Laufzeit" ...
Eben. Wenn ich aber int verwende und annehme, er hätte 32 bit,
hat aber nur 16 bit, bekomme ich nicht unbedingt einen Fehler
beim compilieren, wohl aber u.U. zur Laufzeit.
CU Rollo
Stefan Reuther schrub:
> Zahlreiche Anwendungsfälle kommen ohne das Wissen der exakten
> Bitbreiten aus.
Hm? Ja, wenn du nur 1 bit brauchst, dann ja.
> Ich nutze 'int' zum Beispiel im Wesentlichen
> als 'int_least16_t': für Werte mit einem garantierten
> Wertebereich von +/- 32k, gerne auch mehr.
Klar, überhaupt kein Problem. Nur was hast du gemacht, bevor
dieser Datentyp standardisiert wurde?
Ich fragt ja nur, wieso man anfänglich solche Datentypen mit
garantierter Mindestbreite nicht eingeführt hat.
CU Rollo
> Stefan Reuther schrub:
>
>> Zahlreiche Anwendungsfälle kommen ohne das Wissen der exakten
>> Bitbreiten aus.
>
> Hm? Ja, wenn du nur 1 bit brauchst, dann ja.
Dummschwätzer.
Ich programmiere seit etwa 30 Jahren in C und habe mich selten um die
exakten Bitbreiten gekümmert. Diese kamen eigentlich nur dann ins Spiel,
wenn ich fremde Binärformate auslesen musste.
>> Ich nutze 'int' zum Beispiel im Wesentlichen
>> als 'int_least16_t': für Werte mit einem garantierten
>> Wertebereich von +/- 32k, gerne auch mehr.
>
> Klar, überhaupt kein Problem. Nur was hast du gemacht, bevor
> dieser Datentyp standardisiert wurde?
Was meinst Du mit "bevor dieser Datentyp standardisiert wurde"? Meinst
Du: bevor die _Sprache_ standardisiert wurde? Nun, davor habe ich mich
an das gehalten, was im K&R drin stand.
> Ich fragt ja nur, wieso man anfänglich solche Datentypen mit
> garantierter Mindestbreite nicht eingeführt hat.
Hat man nicht? Ich habe meinen alten K&R (englisch) leider nicht mehr,
kann also nicht nachschauen. Aber meines Wissens war schon damals der
Mindestwertebereich (und damit auch die Mindestbreite) für char, int,
long, unsigned etc. genau so festgelegt wie heute.
Oder meinst Du die neuen Typen (u)int_leastN_t? Nun, wahrscheinlich hat
man damals keine Notwendigkeit dafür gesehen.
Gruß. Claus
> Juergen Ilse schrub:
>
>> Man bekommt die Fehler zur Compile-Time, wenn es den Datentyp
>> int8_t bei der verwendeten Implementierung nicht gibt. Da ist
>> bei C nichts mit "Fehler erst zur Laufzeit" ...
>
> Eben. Wenn ich aber int verwende und annehme, er hätte 32 bit,
Dann machst Du Annahmen, die durch den Standard nicht abgedeckt sind,
und bist fur die Folgen selbst verantwortich.
Wenn Du exakt 32 Bit benötigst, nimmst Du (u)int32_t und bekommst einen
Compilerfehler, wenn der C-Compiler diesen Typ nicht kennt. Wenn Du
etwas Anderes nimmst und darüber Annahmen triffst, die durch den
Standard in keinster Weise abgedeckt sind, bewegst Du Dich auf
gefährlichem Terrain.
Gruß. Claus
Roland Damm <rolan...@arcor.de> wrote:
> Stefan Reuther schrub:
>> Zahlreiche Anwendungsfälle kommen ohne das Wissen der exakten
>> Bitbreiten aus.
> Hm? Ja, wenn du nur 1 bit brauchst, dann ja.
Das ist doch Unfug. Es werden bestimmte Mindestwertebereiche garantiert,
es wird fuer unsigned char nicht nur ein Mindestwertebereich von 0 .. 255
garantiert (der Wertebereich koennte auch groesser sein) sondern es wird
darueber hinaus noch garantiert, dass unsigned char eine "pure binary
representation" ohne Padding oder Parity-Bits hat. Dann auch noch, dass
innerhalb des positiven Wertebereichs von signed char die Representation
von signed char und unsignes char gleich ist. Dann werden auch noch Mindest-
Wertebereiche fuer short, int und long sowie fuer die entsprechenden unsigned
Typen garantiert. Das sind genug Eigenschaften der Integer-Datentypen, um
sehr viele sinnvolle Programme zu schreiben, die keine weiteren Vorgaben
ueber Integer-Typen erfordern (erst recht keine feste Breite). Wenn man
wirklich feste Breiten benoetigt, kann man auf (u)int*_t zurueckgreifen
und erhaelt eben eine Fehlermeldung, wenn die verwendete Implementierung
den gewuenschten Datentyp nicht unterstuetzt. Die Alternative waere es,
mit Datentypen zu arbeiten, die evt. auf der Architektur auf der man den
entsprechenden int*_t Typ momentan nicht zur Verfuegung hat, gar nicht
sinnvoll und effektiv implementierbar sind ... Irgendwie ist mir da die
erste Variante (wie C heute aussieht) doch gar nicht so unsympathisch ...
>> Ich nutze 'int' zum Beispiel im Wesentlichen
>> als 'int_least16_t': für Werte mit einem garantierten
>> Wertebereich von +/- 32k, gerne auch mehr.
> Klar, überhaupt kein Problem. Nur was hast du gemacht, bevor
> dieser Datentyp standardisiert wurde?
Wie waere es mit "int verwendet"? Dieser Datentyp erfuellt die Mindest-
anforderungen an die Breite und ist i.d.R so gewaehlt, dass er (innerhalb
der Anforderungen, die der Standard an diesen Typ stellt) moeglichst
effektiv implementiert ist.
> Ich fragt ja nur, wieso man anfänglich solche Datentypen mit
> garantierter Mindestbreite nicht eingeführt hat.
"Mit garantierter Mindestbreite" gibt es doch: Die "Mindestbreiten" fuer
die Ganzzahltypen lauteb:
char 8 Bit
short 16 Bit
int 16 Bit
long 32 Bit
Ausserdem muss fuer die Wertebereiche dieser Typen gelten:
char <= short <= int <= long
Entsprechendes gilt auch fuer die entsprechenden unsigned Typen.
Roland Damm <rolan...@arcor.de> wrote:
> Juergen Ilse schrub:
>> Man bekommt die Fehler zur Compile-Time, wenn es den Datentyp
>> int8_t bei der verwendeten Implementierung nicht gibt. Da ist
>> bei C nichts mit "Fehler erst zur Laufzeit" ...
> Eben. Wenn ich aber int verwende und annehme, er hätte 32 bit,
> hat aber nur 16 bit,
Dann hast du (sofern du portabel programmieren wolltest) einen Fehler
gemacht. Wenn du mindestens 32 Bit brauchst und deine Implementierung
kein <stdint.h> bietet (weil es z.B. noch kein C99 ist), dann musst
du eben statt int long nehmen, um portabel zu bleiben (fuer long wird
eine Mindestbreite von 32 Bit garantiert).
> Hallo,
>
> Stefan Reuther <stefa...@arcor.de> wrote:
>> Schrieb ich ja schon nebenan: wÀhrend 'int8_t' garantiert den
>> Wertebereich -128 .. +127 hat,
>
> Da bei signerd Datentypen in C auch Einerkomplement-Darstellung moeglich
> ist, kannst du dich bei int8_t nur auf den Wertebereich -127 ... +127
> verlassen.
Nicht bei int8_t, hier wird Zweiwerkomplement verlangt:
7.18.1.1 Exact-width integer types
[#1] 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.
Grüße
Erich
--
EFEU 3.2 is released!
Get the open source from http://efeu.cybertec.at.
Damals wie heute das gleiche: 'int' benutzt. 'int' *ist* eine gültige
und sinnvolle Implementation von 'int_least16_t'.
> Ich fragt ja nur, wieso man anfänglich solche Datentypen mit
> garantierter Mindestbreite nicht eingeführt hat.
Hat man doch. Sie heißen 'char', 'short', 'int' und 'long'.
Stefan
Das ist m.E. kein g�ltiges Beispiel, weil ein Wert au�erhalb des
Bereichs, der in int8_t gespeichert wurde, bereits undefiniertes
Verhalten ausl�st. Da� obiger Code ebenfalls zu undefiniertem
Verhalten f�hrt, spielt dann keine Rolle mehr.
[...]
>> Schrieb ich ja schon nebenan: w�hrend 'int8_t' garantiert den
>> Wertebereich -128 .. +127 hat, kann 'signed char' einen kleineren oder
>> gr��eren Bereich haben. Beides kann zu Fehlern f�hren. Eine Routine
>> void scramble(T p[], size_t n) {
>> static const T map[256] = { ... };
>> for (size_t i = 0; i < n; ++n)
>> p[i] = map[p[i] + 128];
>> }
>> wird halt funktionieren, wenn T 'int8_t' ist, aber nicht, wenn T ein
>> 24-bit-char ist.
>
> Das ist m.E. kein g�ltiges Beispiel, weil ein Wert au�erhalb des
> Bereichs, der in int8_t gespeichert wurde, bereits undefiniertes
> Verhalten ausl�st.
Auch im Jahre des Herrn 2009 kann 'undefiniertes Verhalten' nicht
ausgeloest werden, erst recht nicht auf einem Computer. Allerdings
kann das ausgeloeste Verhalten ggf durch eine bestimmte Referenz, zB
durch die C-Norm, nicht definiert worden sein.
NB: Das richtet sich an Dritte, nicht an den Autor des postings.
Claus Reibenstein schrub:
>> Eben. Wenn ich aber int verwende und annehme, er hätte 32 bit,
>
> Dann machst Du Annahmen, die durch den Standard nicht abgedeckt
> sind, und bist fur die Folgen selbst verantwortich.
>
> Wenn Du exakt 32 Bit benötigst, nimmst Du (u)int32_t und
> bekommst einen Compilerfehler, wenn der C-Compiler diesen Typ
> nicht kennt. Wenn Du etwas Anderes nimmst und darüber Annahmen
> triffst, die durch den Standard in keinster Weise abgedeckt
> sind, bewegst Du Dich auf gefährlichem Terrain.
Sehe ich ja 100% ein. Nur wieso wurden anfänglich in und long und
so so undefiniert definiert? Wem nutzt das? In welchen Fällen
ist (war) es sinnvoll? Wie gesagt, das ist wenn überhaupt nur
von historischem Interesse.
CU Rollo
Juergen Ilse schrub:
> "Mit garantierter Mindestbreite" gibt es doch: Die
> "Mindestbreiten" fuer die Ganzzahltypen lauteb:
>
> char 8 Bit
> short 16 Bit
> int 16 Bit
> long 32 Bit
>
> Ausserdem muss fuer die Wertebereiche dieser Typen gelten:
>
> char <= short <= int <= long
Das heißt aber nur, dass man sich z.B. bei einem int auf 16 Bit
verlassen kann. Mehr kann sein, muss aber nicht. Wenn ich also
15 Bit brauche, kann ich short nehmen. Brauche ich 17 Bit, muss
ich long nehmen. int braucht man also garnicht. Der Typ ist dann
überflüssig.
Wenn ich mit den Prämissen an meinen heutigen PC rangehe, werde
ich nicht selten 50% den Speichers für nichts verschwenden.
Sonderlich hilfreich kommen mir diese Festlegungen eben nicht
vor.
CU Rollo
Roland Damm <rolan...@arcor.de> wrote:
> Juergen Ilse schrub:
>> "Mit garantierter Mindestbreite" gibt es doch: Die
>> "Mindestbreiten" fuer die Ganzzahltypen lauteb:
>>
>> char 8 Bit
>> short 16 Bit
>> int 16 Bit
>> long 32 Bit
>>
>> Ausserdem muss fuer die Wertebereiche dieser Typen gelten:
>>
>> char <= short <= int <= long
>
> Das heißt aber nur, dass man sich z.B. bei einem int auf 16 Bit
> verlassen kann. Mehr kann sein, muss aber nicht. Wenn ich also
> 15 Bit brauche, kann ich short nehmen. Brauche ich 17 Bit, muss
> ich long nehmen.
Ja. Und?
> int braucht man also garnicht. Der Typ ist dann überflüssig.
Nein. Wenn man nur 15 Bit braucht und nicht auf die Speicherbelegung
achten muss, ist man mit int i.d.R. besser bedient, denn es gibt eine
Reihe von CPUs, bei denen int groesser als short ist aber performanter
verarbeitet werden kann als short.
> Wenn ich mit den Prämissen an meinen heutigen PC rangehe, werde
> ich nicht selten 50% den Speichers für nichts verschwenden.
Wenn du auf Speicherverbrauch achten musst, solltest du bei den
15 benoetigten Bits vielleicht doch besser short verwenden. Und
wenn du nicht gerade eine 64-Bit-Umgebung verwendest, wuerdest
du auf den heute ueblichen PCs (ich nehme mal an, du meinst hier
X86 PCs) keinen Speicher verschenken, weil dort dann ueblicher-
weise int und long die selbe Groesse haben und short zu kurz ist
(ich meine jetzt den Fall, wo du mehr als 16 Bit benoetigst).
> Sonderlich hilfreich kommen mir diese Festlegungen eben nicht vor.
Sie sind voellig ausreichend.
> Claus Reibenstein schrub:
>
>>> Eben. Wenn ich aber int verwende und annehme, er hätte 32 bit,
>>
>> Dann machst Du Annahmen, die durch den Standard nicht abgedeckt
>> sind, [...]
>
> Sehe ich ja 100% ein. Nur wieso wurden anfänglich in und long und
> so so undefiniert definiert?
Wieso denn "undefiniert"? Sie waren meines Wissens auch damals schon
genau so definiert wie heute: über ihren Mindestwertebereich. Und der
hat sich IMHO seit K&R nicht geändert.
> Wem nutzt das? In welchen Fällen
> ist (war) es sinnvoll?
Wenn Du Speicher sparen möchtest und mit 16 Bit auskommst, nimmst Du
short. Wenn Du mit 16 Bit auskommst, der tatsächliche Speicherbedarf
aber egal ist, nimmst Du int. In allen anderen Fällen nimmst Du long.
Wo genau ist jetzt Dein Problem?
> Wie gesagt, das ist wenn überhaupt nur
> von historischem Interesse.
Keineswegs. Diese Regeln gelten im Prinzip auch heute noch. Allerdings
gibt es mittlerweile Datentypen wie int_leastN_t, die eine feinere
Typisierung ermöglichen. Ob man die braucht, sei mal dahingestellt. Ich
habe sie bisher noch nicht gebraucht.
Gruß. Claus
> for (size_t i = 0; i < n; ++n)
> p[i] = map[p[i] + 128];
Diese Schleife wird f�r n <= 0 gar nicht und f�r n > 0 unendlich oft
durchlaufen :-)
Gru�. Claus
Wenn ich mich nicht sehr irre, dann hatte ich diese Frage kuerzlich
beantwortet: Lange bevor es eine C-Norm gab, gab es bereits
C-Implementierungen mit 16 Bit breiten ints und mit 32 Bit breiten
ints, wobei 'int' nicht 'Ganzahl einer bestimmten Breite' sondern
'Wortgroesse der Zielarchitektur' impliziert.
Heute mag 'Dein PC' 32 oder 64 Bit breite Mehrzweckregister haben,
aber zum Zeitpunkt der ersten C Standardisierung hatte er nur 16. Und
Deine Waschmaschine duerfte heute noch nicht bei 32 Bit angekommen
sein.
> Wem nutzt das?
Leuten, die den Sinn dahinter verstehen.
Wenn du schon mit dieser Überlegung an das Problem rangehst, solltest du
auch die Tatsache einbeziehen, dass z.B. die Verwendung von short (auf
x86ern) Strafzyklen für Halbwortoperationen generiert, und kommst dann
vielleicht dabei raus, dass du 20% deiner Rechenleistung für die
Reduktion der Resultate auf short verschwendest.
"int" ist halt der Datentyp für "mal eben 'ne Zahl", und zwar eben eine,
die für den Prozessor möglichst "natürlich" zu verarbeiten ist.
Wenn dich andere Kriterien interessieren, zum Beispiel eben Speicher-
effizienz, musst du eben genauer hinschauen. Und dazu gibt's <limits.h>
und <stdint.h>.
Stefan
Stimmt, danke. (Anzumerken ist vielleicht noch, dass 'n < 0' *sehr*
unwahrscheinlich ist.)
Stefan
Warum? Wenn 'T' == 'signed char', dann darf ich da ganz legal SCHAR_MAX
drin speichern. Und wenn 'signed char' einen gr��eren Wertebereich hat
als 'int8_t', dann wird obiger Code undefiniertes Verhalten aufweisen.
Damit ist 'signed char' eben kein Ersatz f�r 'int8_t'. Es ist aber ein
prima Ersatz f�r 'int_least8_t' oder 'int_fast8_t'.
Stefan
> Florian Weimer wrote:
>> * Stefan Reuther:
>>>Schrieb ich ja schon nebenan: w�hrend 'int8_t' garantiert den
>>>Wertebereich -128 .. +127 hat, kann 'signed char' einen kleineren oder
>>>gr��eren Bereich haben. Beides kann zu Fehlern f�hren. Eine Routine
>>> void scramble(T p[], size_t n) {
>>> static const T map[256] = { ... };
>>> for (size_t i = 0; i < n; ++n)
>>> p[i] = map[p[i] + 128];
>>> }
>>>wird halt funktionieren, wenn T 'int8_t' ist, aber nicht, wenn T ein
>>>24-bit-char ist.
>>
>> Das ist m.E. kein g�ltiges Beispiel, weil ein Wert au�erhalb des
>> Bereichs, der in int8_t gespeichert wurde, bereits undefiniertes
>> Verhalten ausl�st.
>
> Warum? Wenn 'T' == 'signed char', dann darf ich da ganz legal SCHAR_MAX
> drin speichern.
Du wei�t das nicht und kannst das auch nicht herausbekommen (anders
als bei C++). Du darfst also nur Werte zwischen -128 und 127
schreiben.
Warum nicht? Nat�rlich wei� ich, welchen Typ ich bei der Deklaration der
Funktion angegeben habe. Und wenn ich da 'signed char' angegeben habe,
und SCHAR_MAX > 127 ist, geht das in die Hose. Wenn ich 'int8_t'
angegeben habe nicht.
Stefan
Wie gesagt: Du mu�t erst mal ein int8_t anlegen, in den Du
legalerweise einen Wert au�erhalb des Bereichs -128 .. 127 gespeichert
hast. Ich sage nicht, da� das unm�glich ist, ich sage nur, da� das
schwierig ist, ohne undefiniertes Verhalten auszul�sen.
> Wie gesagt: Du mu�t erst mal ein int8_t anlegen, in den Du
> legalerweise einen Wert au�erhalb des Bereichs -128 .. 127 gespeichert
> hast. Ich sage nicht, da� das unm�glich ist
Aber ich sage es, und der Standard sagt es auch.
Gru�. Claus
Wo?
> * Claus Reibenstein:
>
>> Florian Weimer schrieb:
>>
>>> Wie gesagt: Du mu�t erst mal ein int8_t anlegen, in den Du
>>> legalerweise einen Wert au�erhalb des Bereichs -128 .. 127 gespeichert
>>> hast. Ich sage nicht, da� das unm�glich ist
>>
>> Aber ich sage es, und der Standard sagt es auch.
>
> Wo?
*seufz* Das haben wir in diesem Thread doch schon alles durchgekaut.
Aber sch�n, von mir aus, extra nochmal f�r Dich:
,----------
| 7.18.1.1 Exact-width integer types
|
| 1 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.
`----------
Aus "two's complement" und "exactly 8 bits" ergibt sich exakt ein
Wertebereich von -128 bis +127.
Alles klar?
Gru�. Claus
7.18.1.1 Exact-width integer types
1 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.
Und mit genau 8 Bit kann man mit der Zweierkomplementdarstellung leider
nichts kleineres als -128 und nichts größeres als 127 abspeichern. Das
verbietet die Mathematik.
Tschö,
Markus
--
Nur weil ein Genie nix reißt, muß ja nun nicht gleich jeder Idiot
pausieren... Bully hats ja auch geschafft.
-- gUnter nanonüm in de.alt.anime
> Florian Weimer schrieb:
>
>> * Claus Reibenstein:
>>
>>> Florian Weimer schrieb:
>>>
>>>> Wie gesagt: Du mußt erst mal ein int8_t anlegen, in den Du
>>>> legalerweise einen Wert außerhalb des Bereichs -128 .. 127 gespeichert
>>>> hast. Ich sage nicht, daß das unmöglich ist
>>>
>>> Aber ich sage es, und der Standard sagt es auch.
>>
>> Wo?
>
> *seufz* Das haben wir in diesem Thread doch schon alles durchgekaut.
> Aber schön, von mir aus, extra nochmal für Dich:
>
> ,----------
> | 7.18.1.1 Exact-width integer types
> |
> | 1 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.
> `----------
>
> Aus "two's complement" und "exactly 8 bits" ergibt sich exakt ein
> Wertebereich von -128 bis +127.
>
> Alles klar?
Nein. Die Frage ist, wie Du ein Objekt vom Typ int8_t anlegst, welches
nicht diesen Wertebereich trägt und nicht undefiniertes Verhalten auslöst.
x = 127; ++x;
ist jedenfalls undefiniert.
> Nein. Die Frage ist, wie Du ein Objekt vom Typ int8_t anlegst, welches
> nicht diesen Wertebereich trägt und nicht undefiniertes Verhalten auslöst.
Gar nicht.
Gruß. Claus
[...]
> Nein. Die Frage ist, wie Du ein Objekt vom Typ int8_t anlegst, welches
> nicht diesen Wertebereich tr�gt und nicht undefiniertes Verhalten ausl�st.
>
> x = 127; ++x;
>
> ist jedenfalls undefiniert.
... jedenfalls insofern man sich der Ansicht anschliesst, dass die in
6.5|5 erwaehnte 'exceptional condition' nicht eine tatsaechliche
Aktivitaet irgendwelcher Hardware darstellt sondern eine Situation,
die irgendjemand fuer aussergewoehnlich haelt obwohl sie das in einer
gegebenen realen Umgebung normalerweise nicht ist und diese
Interpretation sowohl dem gaengigen Benutzung des Terminus' exception
zuwiderlaeuft als auch den verschiedenen Stellen in der C-Norm (zB
7.12.1|1) in denen exceptional conditions als reale Effekte und nicht
als fiktive Konstrukte beschrieben werden.
Ansonsten boete sich
x = 128
an. Das laesst sich naemlich spassigerweise nicht zur
'aussergewoehnlichen Situation' umdeuten, weil das Ergebnis entweder
implementation defined ist oder ein von der Implementierung
definiertes Signal ausgeloest werden soll (6.3.1.3|2), dh es wird in
jedem Fall ein dokumentiertes Verhalten gefordert (und gcc
dokumentiert auch tatsaechlich 'normales' Zweierkomplement-Verhalten).
Eben. Ein Objekt vom Typ 'int8_t' kann keinen Wert außerhalb [-128,127]
haben. Darauf darf sich ein Programm verlassen.
Ausgangspunkt dieses Teilthreads war aber die Behauptung, dass man
'int8_t' immer durch 'signed char' ersetzen könne[1]. Und das geht aus
genau diesem Grund nicht: 'signed char' darf sowohl einen größeren, als
auch einen kleineren Wertebereich als 'int8_t' haben. Es kann Compiler
geben, wo 'signed char x = -128' undefiniert ist, und gibt Compiler, wo
'signed char x = CHAR_MAX' außerhalb von [-128,127] liegt. Also kann man
'int8_t' eben nicht durch 'signed char' ersetzen.
Allerdings kann man sehr wohl 'int_least8_t' durch 'signed char'
ersetzen. Deswegen ist 'int_least8_t' auch verpflichtend, 'int8_t' nur
optional.
Stefan
--
[1] <87tyxxt...@mid.deneb.enyo.de>
Stefan Reuther <stefa...@arcor.de> wrote:
> Ausgangspunkt dieses Teilthreads war aber die Behauptung, dass man
> 'int8_t' immer durch 'signed char' ersetzen könne[1]. Und das geht aus
> genau diesem Grund nicht: 'signed char' darf sowohl einen größeren, als
> auch einen kleineren Wertebereich als 'int8_t' haben. Es kann Compiler
> geben, wo 'signed char x = -128' undefiniert ist, und gibt Compiler, wo
> 'signed char x = CHAR_MAX' außerhalb von [-128,127] liegt. Also kann man
> 'int8_t' eben nicht durch 'signed char' ersetzen.
> Allerdings kann man sehr wohl 'int_least8_t' durch 'signed char'
> ersetzen.
Wirklich? Auch auf Systemen, auf denen signed char nur den Wertebereich
-127 - 127 hat (in Einerkomplement-Darstellung, was ja der Standard durch-
aus zulassen wuerde)?
Dann hat halt auch int_least8_t nur einen Wertebereich von -127 bis
+127. Ich interpretiere jedenfalls 6.2.6.2 so, dass sich eine
Implementierung f�r alle Integertypen entscheiden muss ob
Einerkomplement oder nicht. Einen C-Compiler bei dem int_least8_t
Zweierkomplement ist und signed char Einerkomplement halte ich
f�r nicht zul�ssig.
Streng genommen h�tte man mit einer Einerkomplementmaschine dann ein
kleines Problem bei int8_t, aber so eng darf man das vermutlich nicht
sehen.
Tom