2013-08-29 17 views
7

Dies ist eine weitere Sequenz-Punkt Frage, aber ein ziemlich einfach:Sequenzpunkt vom Funktionsaufruf?

#include <stdio.h> 
void f(int p, int) { 
    printf("p: %d\n", p); 
} 

int g(int* p) { 
    *p = 42; 
    return 0; 
} 

int main() { 
    int p = 0; 
    f(p, g(&p)); 
    return 0; 
} 

dieses undefinierte Verhalten ist? Oder funktioniert der Aufruf an g(&p) als Sequenzpunkt?

Antwort

9

Nein. Es ruft nicht undefined Verhalten auf. Es ist nur nicht näher, da die Reihenfolge, in der die Funktionsargumente ausgewertet werden, im Standard nicht angegeben ist. Die Ausgabe könnte also 0 oder 42 sein, abhängig von der von Ihrem Compiler festgelegten Bewertungsreihenfolge.

+6

Die Frage fragt auch, ob 'g (& p)' als Sequenzpunkt fungiert. Bei der Auswertung von 'g (& p)' gibt es zwei Sequenzpunkte: Zwischen der Auswertung von 'g' und der Auswertung von' & p' und zwischen der Auswertung der "vollen Ausdrücke" '* p = 42;' und der "0" in der "Rückkehr". Aber keiner von ihnen ordnet die Bewertung des Arguments "p" in Bezug auf die Bewertung von "g (& p)" an. –

+0

@EricPostpischil: Toller Kommentar. :-) – Nawaz

4

Das Verhalten des Programms ist nicht spezifiziert, da wir die Reihenfolge der Auswertung der Funktionsargumente nicht kennen, aus dem draft C++ standard1.9Programmausführung Absatz 3:

Bestimmte andere Aspekte und die Operationen der abstrakte Maschinen sind in dieser Internationalen Norm als nicht spezifiziert beschrieben (zum Beispiel Reihenfolge der Auswertung von Argumenten zu einer Funktion). Wenn möglich, definiert diese Internationale Norm eine Reihe zulässiger Verhaltensweisen. [...]

und alle Nebenwirkungen von den Argumenten sequenziert werden, bevor die Funktion eingegeben wird, aus dem Abschnitt 5.2.2Funktionsaufruf Absatz 8:

[Hinweis: Die Bewertungen der postfix Der Ausdruck und die Argumentausdrücke sind alle in Bezug aufeinander unse- quenziert. Alle Nebeneffekte von Argumentauswertungen des Arguments werden sequenziert, bevor die Funktion eingegeben wird (siehe 1.9). -Ende note]

Was C beiden Punkte im C99 draft standard in Abschnitt behandelt werden 6.5.2.2Funktionsaufrufe Ziffer 10:

Die Reihenfolge der Auswertung der Funktion Bezeichner, die tatsächlichen Argumente und Teilausdrücke innerhalb der tatsächlichen Argumente ist nicht angegeben, aber es gibt einen Sequenzpunkt vor dem eigentlichen Aufruf.

So sowohl C und C++ Sie können entweder mit f(0,0) oder f(42,0) enden.