2012-03-29 11 views
5

In cpp, das Ergebnis des folgenden Codeausschnitts ist: 5 5 5 Aber in Java ist das Ergebnis des gleichen Codeausschnitts: 3 5 7 Ich weiß nicht warum, kann es jemand erklären? Vielen Dank!Ausdruckspriorität? Wie geschieht das?

class H 
{ 
    public: 
    H &pr (int n, char * prompt) 
    { 
     cout<<prompt<<n<<" "; 
     return *this; 
    } 

    H &fn(int n) 
    { 
     return pr(n,""); 
    } 
}; 

void test() 
{ 
    int v=3; 
    H h; 
    h.fn(v).fn(v=5).fn((v=7)); 
} 
+2

Die kurze Antwort ist "C++ ist nicht Java." –

+0

BTW, ich liebe Fragen, die mich einige Demontage zerlegen lassen. :) –

Antwort

6

In cpp, das Ergebnis des folgenden Codeausschnitts ist: 5 5 5 Aber in Java ist das Ergebnis desselben Codeausschnitts: 3 5 7 Ich weiß nicht warum,

Weil C++ nicht Java ist :)

Sie mutieren die Variable v in den letzten zwei Funktionsaufrufen. Schauen wir uns die Zerlegen aussehen (debug hier, um die Dinge klarer, in Freigabe ein statischer Wert von 5 verwendet wird, aber es ist auch 7 genauso gut sein könnte, Sie werden sehen, warum.):

h.fn(v).fn(v=5).fn((v=7)); 
00411565 mov   dword ptr [v],7 
0041156C mov   dword ptr [v],5 
00411573 mov   eax,dword ptr [v] 
00411576 push  eax 

Die Reihenfolge Es ist nicht garantiert, dass die Ausdruckauswertung die Reihenfolge ist, in der Sie die Funktionen hier aufrufen. Sie ändern v zwischen sequence points. 7 wird v zugeordnet, dann 5, dann wird die erste Funktion aufgerufen. Beachten Sie, dass es nicht 7 und dann 5 in dieser Reihenfolge sein muss, es könnte ausgetauscht werden! Die Reihenfolge der Auswertung ist nicht spezifiziert, es könnte alles sein.

Sie haben eine Kette von Funktionen, die v zweimal mutieren. Sie können sich nicht darauf verlassen, dass jede Mutation in der Reihenfolge erfolgt, in der Sie sie eingegeben haben.

Wir können es vereinfachen. Nehmen wir an, wir haben zwei Funktionen; x und y, die beide eine int zurückgeben. Wenn ich schreibe:

int k = x() + y(); 

Es gibt keine Garantie dafür, dass x() wird vor y() aufgerufen werden. Wenn Sie also ein für beide Funktionen gemeinsames Argument mutieren, kann die Mutation zuerst im Aufruf von y() auftreten, was Sie sehen.

+1

+1 Um es ein wenig expliziter zu machen: Das Programm hat standardmäßig * Undefined Behaviour * und das bedeutet, dass das Programm grundsätzlich eine der folgenden Ausgaben erzeugen kann: 3 5 6; 3 5 5; 3 7 7; 5 5 5; 5 5 7; 5 7 7; 7 7 7 (und möglicherweise andere, die ich zwischengespielt habe) –

+0

Ich habe es, vielen Dank. – newda

2

Das Problem hier ist, dass der Standard nicht garantiert, wie die Ausdrücke ausgewertet werden.

Na ja, es tut es teilweise, aber wenn Sie diesen Code kompilieren Sie eine spezifische Warnung erhalten, die

heißt
warning: operation on ‘v’ may be undefined 

Ich denke, diese Frage, die Sie über diese Fragen aufklären können: Is this code well-defined?

Verwandte Themen