2010-09-03 11 views
17

OK, ich bin ein wenig embarassed diese Frage zu stellen, aber ich möchte nur sicher sein ...Kurzschlussauswertung und Nebenwirkungen

Es ist bekannt, dass C Kurzschlussauswertung in Booleschen Ausdrücken verwendet:

int c = 0; 
if (c && func(c)) { /* whatever... */ } 

In diesem Beispiel func(c) wird nicht genannt, weil c-0 auswertet. Aber wie wäre es mit einem anspruchsvolleren Beispiel, bei dem die Nebenwirkungen des Vergleichs die Variable, die als nächstes verglichen wird, verändern würden? Wie folgt aus:

int c; /* this is not even initialized... */ 
if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ } 

Funktion canInitWithSomeValue true zurück und ändert Wert bei gegebenen Zeiger im Erfolgsfall. Ist sichergestellt, dass nachfolgende Vergleiche (c == SOMETHING in diesem Beispiel) den Wert canInitWithSomeValue(&c) verwenden?

Egal, wie viel Optimierungen der Compiler verwendet?

+0

Ich denke, Sie können Kurzschlussauswertung und Compiler-Optimierung verwirren. Im ersten Beispiel wird der Compiler die gesamte 'if'-Anweisung optimieren, da sie niemals ausgeführt werden kann. Eine Kurzschlußauswertung würde bedeuten, dass, wenn Sie 'if (func1() && func2()) {...}' und func1() zur Laufzeit ** auf ** ausgewertet hätten (dh nicht beim Kompilieren), dann Der Code sollte 'func2()' nicht überprüfen - der Compiler hätte den Maschinencode so erstellen sollen, dass 'func2()' nicht aufgerufen wird, wenn 'func1()' falsch ist. – Stephen

+0

Dass "int c = 0" da war, um anzuzeigen, dass "c" zum Zeitpunkt des Vergleichs gleich "0" ist, ist mir klar, dass in einem Fall, in dem der Compiler einfach das gesamte if optimieren würde. –

+0

Ah, ich entschuldige mich. Ich habe dich falsch gelesen. Entschuldigen Sie. – Stephen

Antwort

23

ist es, dass spätere Vergleiche garantiert (c == ETWAS in diesem Beispiel) Wert von canInitWithSomeValue (& c) Satz verwendet?

Ja. Da gibt es eine sequence point

Zwischen Auswertung der linken und rechten Operanden des && (logisches AND), || (logisches ODER) und Komma Operatoren. Zum Beispiel werden in dem Ausdruck *p++ != 0 && *q++ != 0 alle Nebeneffekte des Unterausdrucks * p ++! = 0 vor jedem Versuch, auf q zuzugreifen, abgeschlossen.


Eine Sequenz Punkt definiert, jeden Punkt in einer Ausführung des Computerprogramms, bei dem sichergestellt ist, dass alle Nebenwirkungen der bisherigen Bewertungen werden durchgeführt wurden und keine Nebenwirkungen aus nachfolgenden Auswertungen haben noch durchgeführt wurde .

+0

große Antwort, danke! –

5

Ja. Denn beide && und || Operator sind auch so genannte Sequenzpunkte. Letztere definieren, wann die Nebenwirkungen einer vorherigen Operation abgeschlossen sein sollten und die der nächsten nicht begonnen haben sollten.

1

Auswertung innerhalb der If-Anweisung Verbundbedingung ist streng von links nach rechts. Der einzige Umstand, unter dem der zweite Test in Ihrem if optimiert würde, ist, wenn der Compiler mit 100% iger Sicherheit feststellen kann, dass der erste gleich falsch ist.

Verwandte Themen