<ccode> #include <stdio.h> int glob = 0; int a(void) { glob = 1; printf("a\n"); return 1; } int b(void) { glob = 2; printf("b\n"); return 2; } int c(void) { glob = 3; printf("c\n"); return 3; } int main() { printf("%i\n", glob); a()+b()+c(); printf("%i\n", glob); return 0; } </ccode> gehe ich Recht in der Annahme, dass ... a) die Reihenfolge der Aufrufe durch Assoziativität eindeuting festgelegt ist (+ left to right) printet a b c b) die zuweisung zu glob kein undefined behaivour provoziert, weil Funktionsaufruf ein Sequenzpunkt ist. c) undefined behavour wäre glob = a() + b() + c() + ++glob; oder wenn a einen int parameter nehmen würde glob = a(glob++); aber das hier ist vollkommen ok glob = glob++, a(); möchte nur, dass ihr mich verifiziert :) grüsse, daniel
AFAIK ist das alles kein well-formed code. Bei f() + g() ist (meine ich) nicht festgelegt, welche Funktion zuerst aufgerufen wird. Der Compiler wird sich natuerlich fuer eine entscheiden, aber welche, das steht ihm frei. Bei f(g(), h()) bin ich mir sogar sicher, dass nicht festgelegt ist in welcher Reihenfolge die Parameter ausgewertet werden. Davon ganz abgesehen: Selbst wenn das definiert waere, wuerde ich solchen Code niemals schreiben. Wenn du dir schon nicht sicher bist, wie sollen dann andere herausbekommen was die Zeile bedeutet? Wieso nicht einfach ein paar sequence points setzen? a = f(); b = g(); c = h(); d = a + b + c;
Eigentlich ist der Hintergrund einfach die C und C++ Spezifikation aufzufrischen. Dass die Evaluationsreihenfolge der Funktionsparameter dem Compiler überlassen ist, das weiss ich. Ich bin mal böse auf die Schnauze bei folgendem Code gefallen ... #include <iostream> #include <cstdlib> int main() { int i = 0; std::cout << i << '\t' << ++i << std::endl; i = 0; std::cout.operator<<(i).operator<<('\t').operator<<(++i).operator<<(std: :endl); return EXIT_SUCCESS; } i und ++i sind hierbei ohne Sequenzpunkt auf einer Ebene sozusagen. es ist nur weniger sichtbar wenn der Operator << heisst und nicht + komischerweise wird '\t' als int in der 2-ten expliziten Aufrufform interpretiert. grusse, daniel
daniel wrote: > a) die Reihenfolge der Aufrufe durch Assoziativität > eindeuting festgelegt ist (+ left to right) printet Nein. Assoziativität bedeutet nur, in welcher Reihenfolge die Ergebnisse der Funktionsaufrufe bewertet werden, nicht aber, in welcher die Funktionen aufgerufen werden. Daher ist das Verhalten bezüglich der Variablen glob undefined. Es gibt nur wenige Dinge im C-Standard, die dem Compiler eine Vorschrift auferlegen, in welcher Reihenfolge Dinge abzuarbeiten sind. Dazu gehört einerseits der Komma-Operator, andererseits eine verkettete Bedingung.
hmm, Danke aber irgendwie macht es keinen Sinn für mich, vielleicht misverstehe ich etwas. Addition ist doch eine kommutative Operation, wozu dann die Evalutationsreihenfolge (left to right) definieren? Es scheint für mich zumindest nur dann Sinn zu machen, wenn die Seiteneffekte (zB durch Körper der aufgerufenen Funktionen) ins Spiel kommen. grüsse, daniel
daniel wrote: > ich etwas. Addition ist doch eine kommutative Operation, wozu dann > die Evalutationsreihenfolge (left to right) definieren? Wie willst du feststellen, dass die Reihenfolge left to right bei Addition definiert ist oder nicht? Der Compiler muss Code erzeugen, der das korrekte Ergebnis von a + b (bei Integer) erzeugt. Ob er das macht, indem er a in einem Register vorlegt und in dieses Register b addiert, oder anders rum, ist völlig dem Compiler belassen. > Es scheint für mich zumindest nur dann Sinn zu machen, wenn > die Seiteneffekte (zB durch Körper der aufgerufenen Funktionen) ins > Spiel kommen. Wenn Seiteneffekte ins Spiel kommen, ist so gut wie gar nichts mehr garantiert. Brutal ausgedrückt.
hab dazu bei Wiki nochmals explizit die Antwort gefunden http://de.wikibooks.org/wiki/C++-Programmierung:_Ausdr%C3%BCcke_und_Operatoren int x = (a() + b()) + c(); sehe ich das richtig, die Klammerung bleibt also genauso erfolglos? Sie würde die Precedence von 1 Plus erhöhen, aber Reihenfolge ist ein dazu orthogonales Konzept? mir fällt gerade ein Vergleich ein bei f(a(),b(),c()) .. wie die meisten in diesem Fall wissen, kann die Reihenfolge beliebig sein. Wenn man sich jetzt f(x,y,z) als x+y+z implementiert denkt, so sind x,y,z nichts anderes als Parameter dieser Funktion f. Und Parameter werden beliebig zu ihrem Wert evaluirt. Vielleicht einwenig weithergehollt, aber als Eselsbrücke geeignet :) grüsse, Daniel
daniel wrote: > hab dazu bei Wiki nochmals explizit die Antwort gefunden > http://de.wikibooks.org/wiki/C++-Programmierung:_Ausdr%C3%BCcke_und_Operatoren > > int x = (a() + b()) + c(); > sehe ich das richtig, die Klammerung bleibt also genauso erfolglos? Das siehst du absolut 100% richtig.
Karl heinz Buchegger wrote:
> Das siehst du absolut 100% richtig.
Ergänzung: die Klammern sind ja völlig redundant, da sie nur das
ausdrücken, was ohnehin bereits der Fall ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.