Wir verwenden Cookies, um unsere Webseite für Sie zu optimieren. Mit dem Besuch unserer Webseite erklären Sie sich damit einverstanden. // Our website is using cookies to improve your experience. By continuing to browse the site, you are agreeing to our use of cookies.

Weitere Informationen finden Sie in unserer Datenschutzerklärung. // For more information, please refer to our privacy policy.

Toilet Paper 53

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