C Reihenfolge der Operationen - foo () + bar () - Muss foo vor der Bar aufgerufen werden?

7

Im folgenden Code:

%Vor%

Wird vom C-Standard garantiert, dass foo aufgerufen wird, bevor bar aufgerufen wird?

    
David Schwartz 27.04.2012, 22:30
quelle

5 Antworten

12

Nein, es gibt keinen Sequenzpunkt mit + . Es gibt tatsächlich ein Zitat auf der Wikipedia-Seite, das Ihre Frage beantwortet:

  

Betrachte zwei Funktionen f () und g (). In C und C ++ ist der Operator + keinem Sequenzpunkt zugeordnet, und daher ist es im Ausdruck f () + g () möglich, dass entweder f () oder g () zuerst ausgeführt wird.

Ссылка

    
Pubby 27.04.2012, 22:31
quelle
7

Es ist nicht spezifiziert, und im Fall von C99 ist das relevante Zitat 6.5 / 3:

  

Außer wie später angegeben (für den Funktionsaufruf () , && , || , ?: und   Kommaoperatoren), die Reihenfolge der Auswertung von Teilausdrücken und die   Reihenfolge, in der Nebenwirkungen auftreten, sind beide nicht definiert.

In Ihrem Beispiel sind foo() und bar() Unterausdrücke des vollständigen Ausdrucks i = foo() + bar() .

Das "später" für Funktionsaufrufe ist hier nicht direkt relevant, aber als Referenz ist es 6.5.2.2/10:

  

Die Reihenfolge der Auswertung des Funktionsbezeichners, der tatsächlichen   Argumente und Teilausdrücke innerhalb der tatsächlichen Argumente ist   unspezifiziert, aber es gibt einen Sequenzpunkt vor dem eigentlichen Aufruf.

Für && ist es 6.5.13 / 4:

  

Im Gegensatz zur binären binären & amp; Betreiber, der & amp; & amp; Betreiber garantiert   Links-nach-rechts-Bewertung; Es gibt einen Sequenzpunkt nach dem   Auswertung des ersten Operanden.

Da + nicht in der Liste der Operatoren oben steht, sind && und + "anders" als die && und & "anders" sind, und das ist genau das, wonach du fragst. Im Gegensatz zu && , garantiert + nicht die Bewertung von links nach rechts.

    
Steve Jessop 27.04.2012 23:03
quelle
2

Nein, ist es nicht. Die Bewertungsreihenfolge der Argumente von Funktionen und Operatoren ist nicht definiert.

Der Standard sagt nur, dass Aufrufe von foo und bar nicht verschachtelt werden können, was bei der Auswertung von Teilausdrücken ohne Funktionsaufruf vorkommen kann.

    
Rafał Rawicki 27.04.2012 22:31
quelle
0

Nein, das ist nicht definiert. Von K & amp; R Seite 200:

  

Die Reihenfolge der Auswertung von Ausdrücken ist mit gewissen Ausnahmen undefiniert, selbst wenn die Teilausdrücke Nebenwirkungen haben. Das heißt, solange die Definition des Operators nicht garantiert, dass seine Operanden in einer bestimmten Reihenfolge ausgewertet werden, ist die Implementierung frei, Operanden in beliebiger Reihenfolge auszuwerten oder sogar ihre Auswertung zu verschachteln.

Seite 205 von K & amp; R beschreibt die additiven Operatoren und definiert nicht die Reihenfolge des Evaluators der beiden Operanden.

    
Adam Mihalcin 27.04.2012 22:35
quelle
0

Die richtige Antwort, wo ich arbeite, ist "Wenn die Reihenfolge wichtig ist, ist der Code nicht erreichbar, unabhängig davon, was der Standard sagt, wird passieren". Wenn Sie foo () vor bar () ausgewertet haben, müssen Sie foo () vor bar () explizit auswerten. Die Basis dafür ist, dass nicht jeder Programmierer die Standards kennt, und diejenigen, die nicht wissen, ob der ursprüngliche Autor das getan hat.

    
mattnz 27.04.2012 23:55
quelle

Tags und Links