2016-03-22 14 views
1

Ist in folgenden Ausdruck, wenn Ausnahme auf den rhs Abtretungs dh ausgelöst, wenn: bad_alloc wird linesArg bereits verringert werden ?:Auftrag der Auswertung mit Ausnahme

try{  
    buffer[--linesArg] = new char[rows]; 
}catch(std::bad_alloc& ba){ 

} 
+0

Es ist nicht spezifiziert. – molbdnilo

Antwort

5

Zuordnung ist kein sequence point. Daher ist die Reihenfolge der Auswertung von Teilausdrücken nicht spezifiziert. Der Compiler kann eine beliebige Reihenfolge auswählen. Es kann sogar jedes Mal, wenn Sie kompilieren, eine andere Reihenfolge auswählen.

Sie sollten den Ausdruck --linesArg in eine eigene Anweisung extrahieren, um ein wohldefiniertes Verhalten zu erhalten.

+0

Formal ist die Reihenfolge ** nicht spezifiziert **, nicht ** undefiniert **. Informell, ja, es ist undefiniert, aber "undefiniert" hat eine besondere Bedeutung in dem Standard, der hier nicht gilt. Es ist im Allgemeinen besser, sich an den formellen Begriff zu halten, um Verwirrung zu vermeiden (und um pikante Sprachanwälte zu beruhigen). –

+0

@PeteBecker: Du hast Recht, korrigiert. – gexicide

0

Es gibt Sequenzpunkt an; Nachdem die Zuweisung abgeschlossen ist, wird das (so genannte Nebeneffekt) Dekrement sicher stattgefunden haben. Davor ist es nicht spezifiziert.

3

Nein, die Order of evaluation der Operanden ist nicht spezifiziert.

Auftrag der Auswertung der Operanden von fast allen C++ Operatoren (einschließlich der Reihenfolge der Bewertung der Funktionsargumente in einem Funktionsaufruf Ausdruck und die Reihenfolge der Auswertung der Unterausdrücke in jedem Ausdruck) ist nicht spezifiziert. Der Compiler kann Operanden in beliebiger Reihenfolge auswerten und eine andere Reihenfolge wählen, wenn derselbe Ausdruck erneut ausgewertet wird.

Es gibt einige Ausnahmen zu dieser Regel (z. B. für die & , ||, und, Operatoren), die unten aufgeführt sind.

Ansonsten gibt es in C++ kein Konzept von links nach rechts oder von rechts nach links. Dies ist nicht zu verwechseln mit der Assoziativität von Operatoren von links nach rechts und von rechts nach links: Der Ausdruck f1() + f2() + f3() wird als (f1() + f2()) + f3 () aufgrund der Links-zu-Rechts-Assoziativität von Operator +, aber der Funktionsaufruf von f3 kann zur Laufzeit als erstes, letztes oder zwischen f1() oder f2() ausgewertet werden.

buffer[--linesArg] = new char[rows]; 

als

operator=(operator[](buffer, --linesArg), new char[rows]); 

analysiert wird Die Argumente bewertet werden, bevor die Funktion aufgerufen (dh buffer und --linesArg wird vor operator[] genannt ausgewertet werden, operator[]() und new char[rows] wird aufgerufen, bevor operator= ausgewertet werden, nichts mehr.), aber die Reihenfolge der Auswertung der Argumente ist nicht angegeben. Es gibt also keine Garantie, dass --linesArg vor new char[rows] ausgewertet wird.

Es ist besser, die Bestellung klar und eindeutig zu machen, um das unspezifizierte Verhalten zu vermeiden und zu verwirren.

--linesArg; 
buffer[linesArg] = new char[rows]; 
Verwandte Themen