Maison >développement back-end >C++ >Les appels à la méthode de chaînage de code C dans la 4e édition de « Le langage de programmation C » de Stroustrup ont-ils un comportement bien défini ?

Les appels à la méthode de chaînage de code C dans la 4e édition de « Le langage de programmation C » de Stroustrup ont-ils un comportement bien défini ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-23 17:44:021076parcourir

Does the C   Code Chaining Method Calls in Stroustrup's

Ce code de « Le langage de programmation C », 4e édition, section 36.3.6, a-t-il un comportement bien défini ?

Le code en question démontre le chaînage des appels de méthode :

<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>

Cependant, l'assertion échoue dans certains compilateurs comme GCC et Visual Studio, alors qu'elle passe dans Clang.

Le problème

Ce code présente un comportement non spécifié en raison du ordre non spécifié d'évaluation des sous-expressions, car les arguments de fonction sont évalués dans un ordre non séquencé. Les appels de fonction chaînés introduisent un ordre d'évaluation de gauche à droite pour chaque appel de fonction, mais les arguments de chaque appel ne sont séquencés qu'avant l'appel de fonction membre auquel ils appartiennent.

Dans le code, les sous-expressions s .find("even") et s.find(" don't") sont séquencés de manière indéterminée par rapport à s.replace(0, 4, ""). Selon l'ordre d'évaluation, le résultat peut varier en raison d'effets secondaires potentiels.

Ordre d'évaluation non spécifié

Le code peut être décomposé comme suit :

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

A est séquencé avant B, qui est séquencé avant C. Les éléments 1 à 9 sont séquencés de manière indéterminée les uns par rapport aux autres, à l'exception des relations suivantes :

  • 1 à 3 sont séquencés avant B
  • 4-6 sont séquencés avant C
  • 7-9 sont séquencés avant D

Cependant, 4-9 sont séquencés de manière indéterminée par rapport à B. Ce choix d'évaluation l'ordre de 4 et 7 par rapport à B explique les différents résultats entre Clang et GCC.

Ordre d'évaluation des tests

Un programme de test peut être utilisé pour démontrer l'ordre d'évaluation :

<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>

Les résultats diffèrent en fonction de l'ordre d'évaluation de B par rapport à 4 et 7.

C 17 Modifications

C 17 a introduit des modifications dans p0145r3 qui donnent à ce code un comportement bien défini en renforçant l'ordre des règles d'évaluation des expressions postfixées et de leurs listes d'expressions. Plus précisément, cette modification spécifie que toutes les expressions de la liste d'expressions sont séquencées avant la saisie de la fonction. Cela garantit que le code produira le même résultat quel que soit l'ordre d'évaluation des sous-expressions individuelles.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn