Heim >Backend-Entwicklung >C++ >Behält die STL-Methodenverkettung die Auswertungsreihenfolge in C bei?
Behält die Verkettung von STL-Methoden in C die Auswertungsreihenfolge bei?
In Bjarne Stroustrups „The C Programming Language“, 4. Auflage, der folgende Codeausschnitt veranschaulicht die Methodenverkettung:
<code class="cpp">void f2() { std::string s = "but I have heard it works even if you don't believe in it"; s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, ""); assert(s == "I have heard it works only if you believe in it"); }</code>
Dieser Code wertet Anweisungen von links nach rechts aus und ändert die Zeichenfolge s schrittweise. Allerdings ist das Verhalten dieses Ausdrucks je nach verwendetem Compiler mehrdeutig:
Enthüllung des nicht spezifizierten Verhaltens
Der Code zeigt aufgrund der Unbestimmtheit nicht spezifiziertes Verhalten Reihenfolge der Auswertung von Unterausdrücken, obwohl kein undefiniertes Verhalten aufgerufen wird. Der Kern des Problems liegt in der Auswertungsreihenfolge von Funktionsargumenten innerhalb verketteter Funktionsaufrufe.
Insbesondere für die folgenden Unterausdrücke:
Ihre Auswertungsreihenfolge ist unbestimmt in Bezug auf:
Dies bedeutet, dass die Suchaufrufe vor oder nach dem Ersetzungsaufruf ausgewertet werden können, was sich auf die Länge von s und folglich auf die Ergebnisse der Suchaufrufe auswirkt.
Abbildung mit benutzerdefinierter Suchfunktion
Um diese Mehrdeutigkeit zu veranschaulichen, verwendet eine modifizierte Version des Codes eine benutzerdefinierte my_find-Funktion, die die Position der Suchzeichenfolgen in jeder Unterausdrucksauswertung meldet:
<code class="cpp">std::string::size_type my_find(std::string s, const char *cs) { std::string::size_type pos = s.find(cs); std::cout << "position " << cs << " found: " << pos << std::endl; return pos; }</code>
Das Ausführen dieses Codes mit verschiedenen Compilern führt je nach Auswertungsreihenfolge zu unterschiedlichen Ergebnissen:
C 17-Änderungen
Der C 17-Standard (p0145r3) führt Verfeinerungen an den Regeln für die Reihenfolge der Ausdrucksauswertung ein, um diese Mehrdeutigkeit zu beseitigen. Es stärkt die Auswertungsreihenfolge für Postfix-Ausdrücke und ihre Ausdrucksliste wie folgt:
Dadurch wird sichergestellt, dass verkettete Methodenaufrufe in der erwarteten Reihenfolge ausgewertet werden, wodurch dieses undefinierte Verhalten in C 17 behoben wird.
Das obige ist der detaillierte Inhalt vonBehält die STL-Methodenverkettung die Auswertungsreihenfolge in C bei?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!