Discussion:
Problem beim umwandeln von int nach char
(zu alt für eine Antwort)
Bernhart_Diener
2014-04-22 08:40:30 UTC
Permalink
Raw Message
Hallo zusammen,
Man betrachte den folgenden Programmausschnitt:
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...

wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Meine Frage:
_Muss_ der Compiler keine Warnung geben?
Warum?

mfg
BH
Thomas Koller
2014-04-22 12:01:13 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Hallo zusammen,
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Mit "konket" meinst du, "auf deinem Beispielsystem"?
Post by Bernhart_Diener
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Das ganze ist sowieso Compiler/Sysatemabhängig. 'A' + 1 kann irgendein
Zeichen ergeben und muss nicht 'B' sein. (Nicht das du das behauptet
hättest, die Frage ist nur, wozu dient dieses hochzählen?)
Post by Bernhart_Diener
_Muss_ der Compiler keine Warnung geben?
Nein, warum sollte er das müssen?
Post by Bernhart_Diener
Warum?
Eben.

Tom
Rainer Weikusat
2014-04-22 12:22:16 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Hallo zusammen,
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Oder auch nicht: Es gilt sizeof(int) >= sizeof(char).
Post by Bernhart_Diener
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
_Muss_ der Compiler keine Warnung geben?
Warum?
Fuer den Fall, dass sizeof(int) > sizeof(char) ist, wird das Resultat
so nach unsigned char convertiert, dass effektiv folgende Berechung
durchgefuehrt wird:

neues_zeichen = (zeichen + 1) % (UCHAR_MAX + 1)

Ob man das 'Informationsverlust' oder 'typabhaengige Wertkorrektur'
nennen moechte, kommt auf die Umstaende an.
Juergen Ilse
2014-04-22 13:01:00 UTC
Permalink
Raw Message
Hallo,
Post by Bernhart_Diener
Hallo zusammen,
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
... bzw. (wie in diesem Fall) unsigned char nach unsigned int ...
Post by Bernhart_Diener
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
_Muss_ der Compiler keine Warnung geben?
Nein.
Post by Bernhart_Diener
Warum?
Warum sollte er muessen?

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
--
Ein Domainname ist nur ein Name, nicht mehr und nicht weniger.
Wer mehr hineininterpretiert, hat das Domain-Name-System nicht
verstanden.
Bernhart_Diener
2014-04-22 13:36:29 UTC
Permalink
Raw Message
Post by Juergen Ilse
Post by Bernhart_Diener
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
_Muss_ der Compiler keine Warnung geben?
Nein.
Post by Bernhart_Diener
Warum?
Warum sollte er muessen?
Bei dem folgenden Programm gibt der Microsoft Visual C++ Compiler
eine Warnung.
...
int i;
char z;
i = 321;
z = i;
....

Ich dachte , dass dies dann auch für mein - im letzten Posting
dargestellten - Programm gelten muesste.

Wo wird geregelt, wann es eine Warnung geben muss?

mfg
BH
G.B.
2014-04-22 13:48:28 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Wo wird geregelt, wann es eine Warnung geben muss?
Im Anhang I der Norm:

"An implementation may generate warnings in many situations, none of
which are specified as part of this International Standard. "

Alle Hinweise (was ich für eine angemessenere Übersetzung halte
als "Warnung") sind demnach bestenfalls erwartbar.

Die "implicit narrowing conversion" könnte hier eine Rolle spielen.

Alle compiler switches durchprobiert?

Ergänzungstools zum compiler in Anschlag gebracht? ("static
analyzer", MISRA-Knüppel, usf.)

In jedem Fall würde ich die Annahmen dokumentieren,
falls nicht ohnehin beabsichtigt. Nicht nur weil "char"
nicht 8 bits bedeuten muss, oder "int" 4 "bytes", sondern
auch, weil dadurch später noch verständlich ist,
warum welche überall gleichermaßen unbestimmten Typen
verwandt wurden.
Juergen Ilse
2014-04-22 16:42:03 UTC
Permalink
Raw Message
Hallo,

Bernhart_Diener <***@arcor.de> wrote:
[ compiler muss bei drohrnden overflow eines unsigned char nicht warnen ]
Post by Bernhart_Diener
Post by Juergen Ilse
Warum sollte er muessen?
Bei dem folgenden Programm gibt der Microsoft Visual C++ Compiler
eine Warnung.
...
int i;
char z;
i = 321;
z = i;
....
Ich dachte , dass dies dann auch für mein - im letzten Posting
dargestellten - Programm gelten muesste.
Der compiler muss in einem solchen Fall nicht warnen, er duerfte aber.
Der Compiler darf aber auch davor warnen, dass Dienstag ist, dass
der Quelltext eine gerade Anzahl von Zeichen enthaelt oder dass
ueberhaupt versucht wurde etwas zu compilieren ...
Post by Bernhart_Diener
Wo wird geregelt, wann es eine Warnung geben muss?
Wann es eine Warnung geben *muss*, kann man im Sprachstandard nachlesen.

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
--
Ein Domainname ist nur ein Name, nicht mehr und nicht weniger.
Wer mehr hineininterpretiert, hat das Domain-Name-System nicht
verstanden.
Rainer Weikusat
2014-04-22 17:04:49 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Post by Juergen Ilse
Post by Bernhart_Diener
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
_Muss_ der Compiler keine Warnung geben?
Nein.
Post by Bernhart_Diener
Warum?
Warum sollte er muessen?
Bei dem folgenden Programm gibt der Microsoft Visual C++ Compiler
eine Warnung.
...
int i;
char z;
i = 321;
z = i;
....
Ich dachte , dass dies dann auch für mein - im letzten Posting
dargestellten - Programm gelten muesste.
Der entscheidende Unterschied ist hier 'char' anstelle von 'unsigned
char'. Falls char vorzeichenbehaftet ist, sollte hier entweder ein von
der Implementierung abhaengiges Ergebnis produziert werden oder ein
implementierungsabhaengiges Signal stattfinden (es gibt auch Leute, die
'exception' als "Vorgang, der mir aussergewoehnlich erscheint" verstehen
moechten, und nach deren Ansicht hat 6.3.1.3|13 gar keine Bedeutung und
dieser Code undefiniertes Verhalten).

Fuer vorzeichenlose Zahlen ist aber nichts davon der Fall --- hier
muessen die arithmetischen Operatoren immer auf/ in einen "2 hoch irgendwas"
Restklassenring definiert sein (in der Praxis ist das fuer
vorzeichenbehaftete Zahlen "technisch genauso", lediglich definiert C keine
Repraesentation fuer solche weil es da irgendwann im letzten Jahrtausend[*]
mehrere von gab ...)

[*] 1962 oder 1269 oder 1629 oder so ...
Stefan Reuther
2014-04-22 17:16:38 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Bei dem folgenden Programm gibt der Microsoft Visual C++ Compiler
eine Warnung.
...
int i;
char z;
i = 321;
z = i;
....
Ich dachte , dass dies dann auch für mein - im letzten Posting
dargestellten - Programm gelten muesste.
Wo wird geregelt, wann es eine Warnung geben muss?
Nirgends. Der Sprachstandard schreibt nur vor, dass der Compiler bei
bestimmten Fehlern eine Meldung bringen muss. Er trifft keine Aussage
darüber, wie diese Meldung auszusehen hat, und auch nicht darüber,
welche Meldungen der Compiler zusätzlich noch bringen muss/darf.

In deinem Beispiel kommt vielleicht dazu, dass der Überlauf bei
Zuweisung an eine unsigned-Variable wohldefiniert ist, während der
Überlauf bei Zuweisung an eine vorzeichenbehaftete Variable
implementation defined ist. Das ist ein guter Grund für einen Compiler,
bei dem einen zu warnen und bei dem anderen nicht.


Stefan
Hermann Riemann
2014-04-26 11:30:23 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Hallo zusammen,
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Das kann von Compiler und Maschine abhängen.
Wenn ein computer ( IBM ?) keinen Befehl zur Addition für
1 byte hat, muss sie es erst verlängern,
dann addieren, dann abschneiden.

Die Optimierung eines compilers kann eventuell durchaus feststellen
dass das Ziel 1 byte ist, und bei der Addition der
Herkunftswerte nur das jeweils letzte byte der Quellen verwenden.
Post by Bernhart_Diener
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
Post by Bernhart_Diener
_Muss_ der Compiler keine Warnung geben?
Obiger code ist korrektes C

Hermann
der meint, das die Basis Typ Definitionen
in C unvollkommen designed wurden.
--
http://www.Hermann-Riemann.de
Bernhart_Diener
2014-04-27 13:26:32 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
Aber auch bei:
neues_zeichen = zeichen+1;

da
zeichen+1
mehr Byte benoetigt als
zeichen+1

Oder wie siehst du das ?

mfg
BH
Rainer Weikusat
2014-04-27 15:10:42 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Post by Hermann Riemann
Post by Bernhart_Diener
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
neues_zeichen = zeichen+1;
da
zeichen+1
mehr Byte benoetigt als
zeichen+1
Oder wie siehst du das ?
Da gibt es gar nichts zu sehen: Addition plus Zweisung sind nicht so
definiert, wie Du Dir das vorzustellen beliebst: Die Menge, mit der hier
gearbeitet wird, ist ein Restklassenring und keine unendliche Folge
ganzer Zahlen. Insofern ist es unsinnig, hier von 'Datenverlust' zu
sprechen: In ein Gefaess mit einem Liter Rauminhalt kann man keine zwei
Liter Wasser fuellen. Wer das nicht versteht, lernt es vielleicht beim
Aufwischen.
Bernhart_Diener
2014-04-28 17:48:55 UTC
Permalink
Raw Message
Post by Rainer Weikusat
Da gibt es gar nichts zu sehen: Addition plus Zweisung sind nicht so
definiert, wie Du Dir das vorzustellen beliebst: Die Menge, mit der hier
gearbeitet wird, ist ein Restklassenring und keine unendliche Folge
ganzer Zahlen. Insofern ist es unsinnig, hier von 'Datenverlust' zu
sprechen: In ein Gefaess mit einem Liter Rauminhalt kann man keine zwei
Liter Wasser fuellen. Wer das nicht versteht, lernt es vielleicht beim
Aufwischen.
Ich stelle mir es bei dem folgenden Programm so vor:
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...

zeichen wird auf 4 Byte erweitert
(Annahme int --> 4 Byte, unsigned char --> 1 Byte)
00000000 00000000 00000000 01000001
dann 1 addiert:
00000000 00000000 00000000 01000001
+ 00000000 00000000 00000000 00000001
-------------------------------------------------------------------
00000000 00000000 00000000 01000010

Dann werden durch
neues_zeichen = zeichen+1;
die ersten 3 Bytes abgeschnitten
also
neues_zeichen
01000010

und dieses Abschneiden nenne ich Datenverlust

mfg
BH
Rainer Weikusat
2014-04-28 19:30:31 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Post by Rainer Weikusat
Da gibt es gar nichts zu sehen: Addition plus Zweisung sind nicht so
definiert, wie Du Dir das vorzustellen beliebst: Die Menge, mit der hier
gearbeitet wird, ist ein Restklassenring und keine unendliche Folge
ganzer Zahlen. Insofern ist es unsinnig, hier von 'Datenverlust' zu
sprechen: In ein Gefaess mit einem Liter Rauminhalt kann man keine zwei
Liter Wasser fuellen. Wer das nicht versteht, lernt es vielleicht beim
Aufwischen.
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
zeichen wird auf 4 Byte erweitert
(Annahme int --> 4 Byte, unsigned char --> 1 Byte)
Die Groesse eines char-Typs ist immer '1 Byte'.
Post by Bernhart_Diener
00000000 00000000 00000000 01000001
00000000 00000000 00000000 01000001
+ 00000000 00000000 00000000 00000001
-------------------------------------------------------------------
00000000 00000000 00000000 01000010
Dann werden durch
neues_zeichen = zeichen+1;
die ersten 3 Bytes abgeschnitten
Der int-Wert wird in einen 'unsigned char'-Wert konvertiert, in dem so
oft der Wert UCHAR_MAX + 1 davon abgezogen wird, bis das Resultat <=
UCHAR_MAX ist. Fuer den gegebenen Fall passiert also gar nichts, weil
diese Bedingung von Anfang erfuellt ist. Ist sie nicht erfuellt, werden
Addition + Zuweisung, die man auch als

neues_zeichen = zeichen;
zeichen += 1;

ausdruecken koennte, im (in diesem Fall) 'mod 256'-Restklassenring
statt. Dh die Berechung

neues_zeichen = zeichen + 1

ist in Wirklichkeit implizit

neues_zeichen = (zeichen + 1) % 256
Post by Bernhart_Diener
also
neues_zeichen
01000010
und dieses Abschneiden nenne ich Datenverlust
... und die C-Norm nennt das 'implizite Typkonvertierung'. Diese ist
Bestandteil der definierten Semantik dieses komplexen Ausdrucks, genauso
wie

neues_zeichen >>= 8; /* Acht Bit Datenverlusten !!*/

ebenfalls eine definierte Aenderung des Werts hervorruft.
Georg Bauhaus
2014-04-29 08:19:10 UTC
Permalink
Raw Message
Post by Rainer Weikusat
Post by Bernhart_Diener
(Annahme int --> 4 Byte, unsigned char --> 1 Byte)
Die Groesse eines char-Typs ist immer '1 Byte'.
Erwähnenswert ist dann noch, dass 1 byte als die kleinste
Speichereinheit bestimmt ist. Dem entsprechend ist die Oktett-
Annahme mit Vorbehalten versehen, und $programmierer weiß,
ebenfalls nach Annahme, was er oder sie tut. Durchaus mögliche
Überraschung: int mit einer Größe von 2 byte ....

Ich für meinen Teil finde es dann angenehm, wenn in einem Programm
die Annahmen namentlich vermerkt werden, durch ein paar gemäß
diesem Zweck benannte Typ-Aliase, zum Beispiel.
Juergen Ilse
2014-04-29 14:26:28 UTC
Permalink
Raw Message
Hallo,
Post by Georg Bauhaus
Post by Rainer Weikusat
Post by Bernhart_Diener
(Annahme int --> 4 Byte, unsigned char --> 1 Byte)
Die Groesse eines char-Typs ist immer '1 Byte'.
Erwähnenswert ist dann noch, dass 1 byte als die kleinste
Speichereinheit bestimmt ist. Dem entsprechend ist die Oktett-
Annahme mit Vorbehalten versehen, und $programmierer weiß,
ebenfalls nach Annahme, was er oder sie tut. Durchaus mögliche
Überraschung: int mit einer Größe von 2 byte ....
Gemeinste moegliche Ueberraschung: sizeof(long) == 1 ...
(nur moeglich bei CHAR_BIT >= 32). Es gibt IIRC mindestens einen C-Compiler
mit CHAR_BIT == 32 und sizeof(long) == 1.

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
--
Ein Domainname ist nur ein Name, nicht mehr und nicht weniger.
Wer mehr hineininterpretiert, hat das Domain-Name-System nicht
verstanden.
Peter J. Holzer
2014-04-29 19:32:36 UTC
Permalink
Raw Message
Post by Juergen Ilse
Post by Georg Bauhaus
Post by Rainer Weikusat
Post by Bernhart_Diener
(Annahme int --> 4 Byte, unsigned char --> 1 Byte)
Die Groesse eines char-Typs ist immer '1 Byte'.
Erwähnenswert ist dann noch, dass 1 byte als die kleinste
Speichereinheit bestimmt ist. Dem entsprechend ist die Oktett-
Annahme mit Vorbehalten versehen, und $programmierer weiß,
ebenfalls nach Annahme, was er oder sie tut. Durchaus mögliche
Überraschung: int mit einer Größe von 2 byte ....
Gemeinste moegliche Ueberraschung: sizeof(long) == 1 ...
(nur moeglich bei CHAR_BIT >= 32). Es gibt IIRC mindestens einen C-Compiler
mit CHAR_BIT == 32 und sizeof(long) == 1.
<aufzeig>

Bitte, Herr Lehrer, mit sowas habe ich schon gearbeitet.

War ein gcc für einen Motorola 96000 Prozessor. Lustiges Ding. Habe es
aber vorgezogen, Assembler zu verwenden, denn mit dem LIW-Zeugs kam der
gcc 1.x nicht wirklich gut zurecht.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Peter J. Holzer
2014-04-27 17:16:45 UTC
Permalink
Raw Message
Post by Bernhart_Diener
Post by Hermann Riemann
Post by Bernhart_Diener
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
neues_zeichen = zeichen+1;
da
zeichen+1
mehr Byte benoetigt als
zeichen+1
Wie soll "zeichen+1" mehr Byte benötigen als "zeichen+1"? Das ist doch
genau das selbe?

Der Wert zeichen+1 passt genau dann nicht in neues_zeichen, wenn zeichen
den Wert UCHAR_MAX hat. Nur in diesem Fall kommt es zu einem Überlauf
und in neues_zeichen wird der Wert 0 gespeichert. In allen anderen
Fällen ist der in neues_zeichen gespeicherte Wert gleich dem
arithmetisch zu erwartendem Wert.

Ob man diesen Überlauf als "Datenverlust" bezeichnen will, ist eine
Frage der Semantik. Was sollte denn zeichen+1 im Fall von UCHAR_MAX
sein? Welches Zeichen kommt nach dem letzten? Ist der Versuch, das
Zeichen nach dem letzten Zeichen zu berechnen überhaupt sinnvoll?

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Thomas Koller
2014-04-28 07:33:05 UTC
Permalink
Raw Message
Post by Hermann Riemann
Post by Bernhart_Diener
Hallo zusammen,
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Das kann von Compiler und Maschine abhängen.
Wenn ein computer ( IBM ?) keinen Befehl zur Addition für
1 byte hat, muss sie es erst verlängern,
dann addieren, dann abschneiden.
Die Optimierung eines compilers kann eventuell durchaus feststellen
dass das Ziel 1 byte ist, und bei der Addition der
Herkunftswerte nur das jeweils letzte byte der Quellen verwenden.
Post by Bernhart_Diener
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
Praktisch unwahrscheinlich, aber es kann auch bei 'A'+1 zu einem Überlauf
kommen. Ob man das Datenverlust nennen will ist einer andere Frage.

Tom
Rainer Weikusat
2014-04-28 10:50:34 UTC
Permalink
Raw Message
Post by Thomas Koller
Post by Hermann Riemann
Post by Bernhart_Diener
Hallo zusammen,
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Das kann von Compiler und Maschine abhängen.
Wenn ein computer ( IBM ?) keinen Befehl zur Addition für
1 byte hat, muss sie es erst verlängern,
dann addieren, dann abschneiden.
Die Optimierung eines compilers kann eventuell durchaus feststellen
dass das Ziel 1 byte ist, und bei der Addition der
Herkunftswerte nur das jeweils letzte byte der Quellen verwenden.
Post by Bernhart_Diener
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
Praktisch unwahrscheinlich, aber es kann auch bei 'A'+1 zu einem Überlauf
kommen.
Es duerfte zu einem Ueberlauf kommen, dh eine Implementierung, bei der
'A' + 1 ausserhalb des Wertebereichs von int laege, waere
standard-konform. Das heisst aber nicht, dass es eine solche
Implementierung auch tatsaechlich gibt, es also zu einem Ueberlauf
kommen kann.
Thomas Koller
2014-04-28 11:58:47 UTC
Permalink
Raw Message
Post by Rainer Weikusat
Post by Thomas Koller
Post by Hermann Riemann
Post by Bernhart_Diener
Hallo zusammen,
...
unsigned char zeichen='A';
unsigned char neues_zeichen;
neues_zeichen = zeichen+1;
...
wenn man in einem Befehl die zwei (gemischten) Datentypen int und char
hat (1 ist int und zeichen bzw. neues_zeichen ist char), wird doch
zuerst char in int umgewandelt.
Konket wird zeichen auf 4 Byte erweitert und dann 1 dazuaddiert.
Aber dann wird doch dieses 4 Byte Ergebnis in einem Byte (naemlich
char neues_zeichen) abgespeichert.
Das kann von Compiler und Maschine abhängen.
Wenn ein computer ( IBM ?) keinen Befehl zur Addition für
1 byte hat, muss sie es erst verlängern,
dann addieren, dann abschneiden.
Die Optimierung eines compilers kann eventuell durchaus feststellen
dass das Ziel 1 byte ist, und bei der Addition der
Herkunftswerte nur das jeweils letzte byte der Quellen verwenden.
Post by Bernhart_Diener
Es gibt also einen moeglichen Datenverlust (von 4 Byte auf 1 Byte).
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
Praktisch unwahrscheinlich, aber es kann auch bei 'A'+1 zu einem Überlauf
kommen.
Es duerfte zu einem Ueberlauf kommen, dh eine Implementierung, bei der
'A' + 1 ausserhalb des Wertebereichs von int laege, waere
standard-konform. Das heisst aber nicht, dass es eine solche
Implementierung auch tatsaechlich gibt, es also zu einem Ueberlauf
kommen kann.
Auf was willst du hinaus? Das hatte ich doch geschrieben.

Tom
Rainer Weikusat
2014-04-28 15:27:10 UTC
Permalink
Raw Message
[...]
Post by Thomas Koller
Post by Rainer Weikusat
Post by Thomas Koller
Post by Hermann Riemann
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
Praktisch unwahrscheinlich, aber es kann auch bei 'A'+1 zu einem Überlauf
kommen.
Es duerfte zu einem Ueberlauf kommen, dh eine Implementierung, bei der
'A' + 1 ausserhalb des Wertebereichs von int laege, waere
standard-konform. Das heisst aber nicht, dass es eine solche
Implementierung auch tatsaechlich gibt, es also zu einem Ueberlauf
kommen kann.
Auf was willst du hinaus? Das hatte ich doch geschrieben.
Unter "es ist unwahrscheinlich aber kann passieren" wuerde ich
verstehen, das mit einer Wahrscheinlichkeit von 0.0000x die Addition 'A'
+ 1 auf einem ASCII-System einen Wert jenseits des Wertebereichs von int
ergibt. Und das kann nicht passieren. Aber es duerfte (insoweit es die
C-Norm angeht) Implementierungen geben, bei denen das Resultat
ausserhalb dieses Wertebereichs laege.

Ich neige allerdings dazu, Dinge woertlicher zu verstehen, als sie
gemeint sind, insofern koennte das auch ein Missverstaendnis meinerseits
sein.
Thomas Koller
2014-04-29 16:31:43 UTC
Permalink
Raw Message
Post by Rainer Weikusat
[...]
Post by Thomas Koller
Post by Rainer Weikusat
Post by Thomas Koller
Post by Hermann Riemann
Ein Datenverlust entsteht bei Überlauf (nicht bei 'A'+1)
Praktisch unwahrscheinlich, aber es kann auch bei 'A'+1 zu einem Überlauf
kommen.
Es duerfte zu einem Ueberlauf kommen, dh eine Implementierung, bei der
'A' + 1 ausserhalb des Wertebereichs von int laege, waere
standard-konform. Das heisst aber nicht, dass es eine solche
Implementierung auch tatsaechlich gibt, es also zu einem Ueberlauf
kommen kann.
Auf was willst du hinaus? Das hatte ich doch geschrieben.
Unter "es ist unwahrscheinlich aber kann passieren" wuerde ich
verstehen, das mit einer Wahrscheinlichkeit von 0.0000x die Addition 'A'
+ 1 auf einem ASCII-System einen Wert jenseits des Wertebereichs von int
ergibt. Und das kann nicht passieren.
Du hast doch gerade bestätigt, dass es doch passieren kann, es bräuchte nur
jemand einen entsprechenden Zeichensatz definieren. Auch wenn es
unwahrscheinlich ist, dass jemand sowas tatsächlich mal machen wird.
Post by Rainer Weikusat
Aber es duerfte (insoweit es die
C-Norm angeht) Implementierungen geben, bei denen das Resultat
ausserhalb dieses Wertebereichs laege.
Eben.
Post by Rainer Weikusat
Ich neige allerdings dazu, Dinge woertlicher zu verstehen, als sie
gemeint sind, insofern koennte das auch ein Missverstaendnis meinerseits
sein.
Ich geh davon aus, dass es ein Missverständnis zwischen uns war, auch
wenns nicht an der wörtlichen Auslegung liegt.

Tom
Loading...