Auch wenn's jetzt in dem Fall keine Rolle spielt, solltest du mal deine Optionen updaten. -ansi führt dazu, dass der Compiler auf das 35 Jahre alte ANSI-C zurückschaltet.
-ansi führt dazu, dass der Compiler auf das 35 Jahre alte ANSI-C
zurückschaltet.
Wo ist da der Vorteil? Die Erklärung hast du offen gelassen.
Na dass eben alle Features, die der Sprache in den letzten 35 Jahren hinzugefügt wurden, genutzt werden können. "Bauform" hat ja schon ein paar davon gelistet. Wobei gcc manche auch mit -ansi fälschlicherweise durchlässt, wie z.B. bool oder stdint.h, die es in C89 eigentlich nicht gibt.
Im Nachhinein habe ich eine
Vermutung warum das Ergebnis bei a + b anders ist als bei c.
Da braucht man nichts zu vermuten.
Alle Berechnungen erfolgen immer so, als wären sie mindestens int. Und auch printf(%d) erwartet int, d.h. bei Bedarf erfolgt eine Erweiterung auf int.
Allein die Zuweisung auf c schneidet das höherwertige Byte wieder ab.
-ansi führt dazu, dass der Compiler auf das 35 Jahre alte ANSI-C
zurückschaltet.
Wo ist da der Vorteil? Die Erklärung hast du offen gelassen.
Na dass eben alle Features, die der Sprache in den letzten 35 Jahren
hinzugefügt wurden, genutzt werden können. "Bauform" hat ja schon ein
paar davon gelistet. Wobei gcc manche auch mit -ansi fälschlicherweise
durchlässt, wie z.B. bool oder stdint.h, die es in C89 eigentlich nicht
gibt.
Ach shit, ich hatte das genau anders verstanden. Ich hatte es erst so verstanden dass er -ansi nutzen soll und kratzte mich am Kopf und fragte mich... äh? Dann geht ja "nichts" mehr :)
Aber eben habe ich gesehen, dass du eigentlich wolltest, dass er -ansi aus seinen angegebenen Optionen streicht. Ich hatte die Option irgendwie übersehen.
Bauform hat ja schöne Beispiele gebracht.
Ich nutze mal eine IDE im Job, die -ansi default setze wenn man ein Projekt erzeugte. Das war das erste was ich gestrichen habe.
Mir ist das Verhalten in so weit klar, als das bei C das Verhalten bei underflow und overflow von signed char oder signed int, im Gegensatz zu unsigned char oder unsigned int, nicht definiert ist.
Mir ist das Verhalten in so weit klar, als das bei C das Verhalten bei
underflow und overflow von signed char oder signed int, im Gegensatz zu
unsigned char oder unsigned int, nicht definiert ist.
Richtig, aber der Wertebereich von signed int ist auf jeden Fall groß genug, um den von dir verwendeten Zahlenbereich abzudecken, daher gibt es hier außer bei ++ und -- kein Problem.
Denn wie oben schon erwähnt wurde:
c erst mal auf int erweitert wird und dann die Berechnung mit dem Typ durchgeführt wird. Das Ergebnis ist natürlich dann auch vom Typ int. Somit kann da nix überlaufen, weil der Wertebereich von int groß genug ist, um das Ergebnis aufzunehmen.
Hier ist es das gleiche. Dein Cast ändert daran nichts. Es wird durch ihn die 1 lediglich erst nach signed char konvertiert, bevor sie dann sofort wieder (wie die Variable c) nach int konvertiert wird. Die Berechnung erfolgt dann auch wieder mit Typ int.
Lediglich bei --c und ++c gibt es ein Problem, weil da das Ergebnis ja wieder nach c zurückgeschrieben wird, das aber nicht groß genug dafür ist.
Weil c in beiden Fällen uninitialisiert ist und dein Code dadurch undefiniertes Verhalten auslöst. Aber ich vermute, du wolltest hier c mit SCHAR_MAX initialisieren. Dann hast du aber trotzdem undefiniertes Verhalten, weil eben der Wertebereich von c nicht mehr ausreicht.
Laut C-Standard ist ++c äquivalent zu c+=1 ("The expression ++E is equivalent to (E+=1), where the value 1 is of the appropriate type.")
und das wiederum ist (mit der Ausnahme dass c nur einmal evaluiert wird) äquivalent zu c = c + 1. ("A compound assignment of the form E1 op= E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with respect to an indeterminately sequenced function call, the operation of a compound assignment is a single evaluation")
Da das Verhalten in diesem Fall undefiniert ist, muss das Ergebnis aber nicht gleich sein.
der entscheidende Punkt ist wohl, dass man zwischensigned char c;
c = SCHAR_MAX;
printf("%d", c + 1);
undsigned char c;
c = SCHAR_MAX;
c = c + 1;
printf("%d", c);
unterscheiden muss. Im ersten Fall ist der Wertebereich int und im
zweiten Fall signed char.
Ja, weil du im zweiten Fall das Ergebnis nach c zurückschreibst, das vom Typ signed char ist, in den es aber nicht reinpasst. Im ersten Fall dagegen verarbeitest du das Ergebnis der Addition direkt als int weiter. Somit läuft da nichts über. Würdest du schreiben:
1
intd=c+1:
dann wäre das Ergebnis das gleiche wie im ersten Fall.