Auswertungsreihenfolge

Andi_CH

Top Contributor
Ich bin heute auf ein ähnliches Konstrukt gestossen wie das folgende.
Java:
	x = 1;
	z = (x++)+x;
	System.out.println("z = " + z);
// Resultat 3
	x = 1;
	z = x+(x++);
	System.out.println("z = " + z);
// Resultat 2

Ich finde das extrem gefährlich, vor allem weil es in einem recht komplexen Ausdruck ist, x eine Klassenvariable ist und in einer Unterfunktion verändert wird.

Ist streng definiert in welcher Reihenfolge die Terme berechnet werden?

Ich bin nicht wirklich fündig geworden, aber beim Suchen noch auf einen herrlichen Ausdruck gestossen:
Betrachten wir das flogende als kleines Rätsel :) - da brauch ich nicht keine Antworten, denn ich würde so etwas niemals ausnutzen ;-)

Java:
int x = 1;
int y = 2;
x = x+++y;
// Was ist das Resultat?

Java:
int x = 1;
int y = 2;
x = (x++)+y;
// Was ist das Resultat?

Java:
int x = 1;
int y = 2;
x = x+(++y);
// Was ist das Resultat?

Warum gibt Zeile 3 einen Kompilationsfehler. Zeile 4 ist nämlich ok
Java:
int x = 1;
int y = 2;
x = x+++++y;
z = x++-++y;

Das verstehe ich aber wirklich nicht. Die letzte Zeile (und nur die letzte) ist falsch.
Ja ich weiss, es ist sinnlos, aber es könnten ja auch "-" sein, dann mach -x Sinn ;-)
Java:
int x = +3;
int y = +x;
y = ++x;
y = +(++x);
y = ++(+x);
 
S

SlaterB

Gast
Das verstehe ich aber wirklich nicht. Die letzte Zeile (und nur die letzte) ist falsch.
Ja ich weiss, es ist sinnlos, aber es könnten ja auch "-" sein, dann mach -x Sinn ;-)
gerade mit - wirds deutlicher: ++(-x)
++ ist nicht einfach eine +1-Rechnung, sondern soll eine Variable ändern,
auf -x, +x oder sonst einen (ausgerechneten) Wert wie (1+2) geht das nicht
 
T

tommysenf

Gast
Ich bin heute auf ein ähnliches Konstrukt gestossen wie das folgende.
Java:
	x = 1;
	z = (x++)+x;
	System.out.println("z = " + z);
// Resultat 3
	x = 1;
	z = x+(x++);
	System.out.println("z = " + z);
// Resultat 2

Ich finde das extrem gefährlich, vor allem weil es in einem recht komplexen Ausdruck ist, x eine Klassenvariable ist und in einer Unterfunktion verändert wird.

Ist streng definiert in welcher Reihenfolge die Terme berechnet werden?

Beide Terme sind gleichwertig und entsprechen der folgendem:

Java:
z = x + x;
x = x +1;

da x++ immer erst nach Auswertung des Terms ausgeführt wird. (im Gegensatz zu ++x).

Trotzdem nutzt der Code im Falle, dass x eine Membervariable ist, Seiteneffekte aus. Das zeugt dann nicht gerade von gutem Stil.
 

Purgator

Aktives Mitglied
Wow, ich muss echt Danke sagen für den Beitrag.
Brauchte sogar eine Weile bis ich überhaupt verstand warum einmal 2 und einmal 3 rauskommt - ist ja direkt gefährlich das zu nutzen ;) .
 

Andi_CH

Top Contributor
Natürlich ist es sehr gefährlich so etwas zu nutzen, weil der Kompiler nicht das Mass aller Dinge darstellt!
Der Mensch erkennt eben nicht auf den ersten Blick was Sache ist und somit ist der Code extrem schlecht wartbar. (Es gab (gibt?) einen Wettbewerb bei dem es darum geht die unleserlichste Zeile C-Code zu schreiben - lassen wir denen den Spass - wir müssen das nicht toppen :D )

So etwas wird wohl hoffentlich beim ersten Codereview mit klärenden Klammern versehen ;-)

Mein ursprüngliche Frage war aber eine Andere:

Jede der Funktionen fn verwendet x.
Eine Unterfunktion einer Unterfunktion von z.B. f3 verändert x (es muss jetzt nicht disktuiert werden ob das unschön oder unschön ist ... es ist :wuerg: !)

Java:
int x = 42;
y = f1() + f2() + f3() * f4() + f5();

Wenn ich das Kapitel 15.7 in dem da richtig interpretiere, müsste es zwingend so sein:

f1(), f2(), +, f3(), f4(), *, +, f5(), +, Zuweisung

Seht ihr das auch so?
 
Zuletzt bearbeitet:

Andi_CH

Top Contributor
Java:
    x = 1;
    z = (x++)+x;
    System.out.println("z = " + z);
// Resultat 3
    x = 1;
    z = x+(x++);
    System.out.println("z = " + z);
// Resultat 2

Beide Terme sind gleichwertig und entsprechen der folgendem:

Java:
z = x + x;
x = x +1;

da x++ immer erst nach Auswertung des Terms ausgeführt wird. (im Gegensatz zu ++x).

Trotzdem nutzt der Code im Falle, dass x eine Membervariable ist, Seiteneffekte aus. Das zeugt dann nicht gerade von gutem Stil.

Und genau diese Behauptung stimmt nicht - die unterschiedlichen Ausgabewerte beweisen das ja.

Ganz offensichtlich wird x im ersten Fall inkrementiert bevor die Addition ausgeführt wird.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
The International Obfuscated C Code Contest

Ich finde auch, dass man bei sowas eher "konservativ" sein sollte. Code wird höchstens(!) ein mal geschrieben, aber potentiell hunderte oder tausende Male gelesen. Z.B. würde ich es unbedingt vermeiden wollen, Code zu schreiben, bei dem der Unterschied zwischen ++i und i++ relevant ist. Lieber drei triviale Zeilen, als eine Zeile, bei der man nicht weiß, was gemacht wird.
 

Neue Themen


Oben