Toilet Paper 53

Auswertungsreihenfolge in C, Objective-C und C++

Problem

Die Auswertungsreihenfolge der Operanden eines beliebigen C-Operators (Objective-C oder C++) ist nicht festgelegt (sofern nicht nachstehend angegeben). Dies umfasst die Auswertungsreihenfolge von Funktionsargumenten bei einem Funktionsaufruf und die Auswertungsreihenfolge von Teilausdrücken in einem beliebigen Ausdruck. Der Compiler wertet sie in beliebiger Reihenfolge aus und wählt möglicherweise eine andere Reihenfolge, wenn derselbe Ausdruck erneut ausgewertet wird.

Vorteil: Es vereinfacht die Arbeit des Compilers und ermöglicht in bestimmten Situationen die Erzeugung von sehr effizientem Code.

Nachteil: Nebeneffekte! Sie hängen nicht nur von spezifischer Hardware, Plattform und Compiler ab, sondern auch von bestimmten Einstellungen (Optimierungsstufe, Debug- / Release-Version) desselben Compilers. Schlussendlich führt das zu einem nicht-portierbarem Code und schwer zu erkennenden Bugs.

Beispiele

• Auswertungsreihenfolge der Operanden eines beliebigen Operators (z. B. +, -, =, *, /)

Ausnahmen:

  1. logische Operatoren (&& und ||)
  2. logischer Operator (?:)
  3. Komma-Operator ,
Order of evaluation in C, Objective C and C++

Erstaunlicherweise könnte die Ausgabe jede der folgenden sein: „1 2 3“, „2 1 3“, „3 2 1“, „2 1 3“, „1 3 2“ und „3 1 2“!

Der Ausdruck f1 () + f2 () + f3 () wird aufgrund der Links-Rechts-Assoziativität des Operators + als (f1 () + f2 ()) + f3 () geparsed. Der Funktionsaufruf von f3 wird entweder zuerst, als letztes oder zwischen f1 () oder f2 () zur Laufzeit ausgewertet.

Die Reihenfolge der Auswertung von Funktionsargumenten in einem Funktionsaufruf:

Order of evaluation in C, Objective C and C++

Ergebnisse:

  • Das Ergebnis mit Clang / PPC-Architektur
  • Das Ergebnis mit Clang / i386-Architektur
Order of evaluation in C, Objective C and C++

Nachfolgend wir die Lösung des Problems gezeigt.

Lösung

Order of evaluation in C, Objective C and C++

Keinen Code schreiben, der von der Reihenfolge der Auswertung abhängt (der Nebeneffekte hat)!

  • Compiler-Warnungen aktivieren und beachten
  • Statische Analysetools (wie der von Clang, cppcheck usw.) nutzen, um noch mehr Warnungen zu erhalten

Weitere Aspekte
Undefiniertes Verhalten ist ein Verhalten, das bei verschiedenen Implementierungen einer Programmiersprache variieren kann. Das genaue Verhalten kann bei der Untersuchung des zugehörigen Quellcodes nicht vollständig ermittelt werden.

---

Autor:

Andreas Maier, Software Architect, Business Division Banking & Insurance

Cookie-Einstellungen

Diese Website verwendet Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und Zugriffe auf die Website zu analysieren. Zudem werden Informationen zu Ihrer Verwendung der Website an Partner für soziale Medien, Werbung und Analysen weitergegeben. Die Partner führen diese Informationen möglicherweise mit weiteren Daten zusammen, die Sie ihnen bereitgestellt haben oder die sie im Rahmen Ihrer Nutzung der Dienste gesammelt haben.

Weitere Informationen finden Sie in unserer Datenschutzerklärung. Dort können Sie nachträglich auch Ihre Cookie-Einstellungen ändern.

contact icon

Kontakt aufnehmen