Heim  >  Artikel  >  Backend-Entwicklung  >  Verfügen die C-Code-Verkettungsmethodenaufrufe in Stroustrups „The C Programming Language“, 4. Auflage, über ein wohldefiniertes Verhalten?

Verfügen die C-Code-Verkettungsmethodenaufrufe in Stroustrups „The C Programming Language“, 4. Auflage, über ein wohldefiniertes Verhalten?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-23 17:44:02966Durchsuche

Does the C   Code Chaining Method Calls in Stroustrup's

Verfügt dieser Code aus „The C Programming Language“, 4. Ausgabe, Abschnitt 36.3.6 über ein wohldefiniertes Verhalten?

Der fragliche Code zeigt verkettete Methodenaufrufe:

<code class="cpp">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>

Allerdings schlägt die Behauptung in bestimmten Compilern wie GCC und Visual Studio fehl, während sie in Clang übergeben wird.

Das Problem

Dieser Code zeigt aufgrund der nicht spezifizierte Reihenfolge der Auswertung von Unterausdrücken, da Funktionsargumente in einer nicht sequenzierten Reihenfolge ausgewertet werden. Verkettete Funktionsaufrufe führen für jeden Funktionsaufruf eine Auswertungsreihenfolge von links nach rechts ein, aber die Argumente jedes Aufrufs werden nur vor dem Mitgliedsfunktionsaufruf, zu dem sie gehören, sequenziert.

Im Code sind die Unterausdrücke s .find("even") und s.find(" don't") sind in Bezug auf s.replace(0, 4, "") unbestimmt sequenziert. Je nach Auswertungsreihenfolge kann das Ergebnis aufgrund möglicher Nebenwirkungen variieren.

Unbestimmte Auswertungsreihenfolge

Der Code lässt sich wie folgt aufschlüsseln:

s.replace(0, 4, "" )                  // A
    .replace( s.find( "even" ), 4, "only" )    // B
        .replace( s.find( " don't" ), 6, "" );   // C

A wird vor B sequenziert, das vor C sequenziert wird. Die Elemente 1–9 werden in unbestimmter Reihenfolge zueinander angeordnet, mit Ausnahme der folgenden Beziehungen:

  • 1–3 werden vor B sequenziert
  • 4-6 werden vor C sequenziert
  • 7-9 werden vor D sequenziert

4-9 werden jedoch in Bezug auf B unbestimmt sequenziert. Diese Wahl der Bewertung Reihenfolge für 4 und 7 in Bezug auf B erklärt die unterschiedlichen Ergebnisse zwischen Clang und GCC.

Testen der Bewertungsreihenfolge

Ein Testprogramm kann verwendet werden, um die Bewertungsreihenfolge zu demonstrieren:

<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 in complete expression: "
        << pos << std::endl ;

    return pos ;
}

int main()
{
   std::string s = "but I have heard it works even if you don't believe in it" ;
   std::string copy_s = s ;

   std::cout << "position of even before s.replace(0, 4, \"\" ): " 
         << s.find( "even" ) << std::endl ;
   std::cout << "position of  don't before s.replace(0, 4, \"\" ): " 
         << s.find( " don't" ) << std::endl << std::endl;

   copy_s.replace(0, 4, "" ) ;

   std::cout << "position of even after s.replace(0, 4, \"\" ): " 
         << copy_s.find( "even" ) << std::endl ;
   std::cout << "position of  don't after s.replace(0, 4, \"\" ): "
         << copy_s.find( " don't" ) << std::endl << std::endl;

   s.replace(0, 4, "" ).replace( my_find( s, "even" ) , 4, "only" )
        .replace( my_find( s, " don't" ), 6, "" );

   std::cout << "Result: " << s << std::endl ;
}</code>

Die Ergebnisse unterscheiden sich je nach Auswertungsreihenfolge von B in Bezug auf 4 und 7.

C 17-Änderungen

C 17 führte Änderungen in p0145r3 ein, die diesem Code ein genau definiertes Verhalten verleihen durch Stärkung der Reihenfolge der Auswertungsregeln für Postfix-Ausdrücke und deren Ausdruckslisten. Diese Änderung legt insbesondere fest, dass alle Ausdrücke in der Ausdrucksliste sequenziert werden, bevor die Funktion eingegeben wird. Dadurch wird sichergestellt, dass der Code unabhängig von der Auswertungsreihenfolge der einzelnen Unterausdrücke das gleiche Ergebnis liefert.

Das obige ist der detaillierte Inhalt vonVerfügen die C-Code-Verkettungsmethodenaufrufe in Stroustrups „The C Programming Language“, 4. Auflage, über ein wohldefiniertes Verhalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn