Maison  >  Article  >  développement back-end  >  Le chaînage de méthodes STL préserve-t-il l’ordre d’évaluation en C ?

Le chaînage de méthodes STL préserve-t-il l’ordre d’évaluation en C ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-24 03:28:01500parcourir

Does STL Method Chaining Preserve Evaluation Order in C  ?

Le chaînage des méthodes STL en C préserve-t-il l'ordre d'évaluation ?

Dans la 4e édition de "The C Programming Language" de Bjarne Stroustrup, l'extrait de code suivant illustre le chaînage de méthodes :

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

Ce code évalue les instructions de gauche à droite, en modifiant la chaîne s progressivement. Cependant, le comportement de cette expression est ambigu selon le compilateur utilisé :

  • Clang: L'évaluation suit l'ordre attendu, ce qui donne des s du type "J'ai entendu dire que cela ne fonctionne que si vous y croyez".
  • GCC :L'ordre d'évaluation est imprévisible, ce qui fait que s prend une valeur incorrecte.
  • Visual Studio : Semblable à GCC, l'évaluation est ambiguë, produisant souvent le même résultat incorrect.

Dévoilement du comportement non spécifié

Le code présente un comportement non spécifié en raison de l'indétermination ordre d'évaluation des sous-expressions, même s'il n'invoque pas de comportement indéfini. Le nœud du problème réside dans l'ordre d'évaluation des arguments de fonction dans les appels de fonction chaînés.

Plus précisément, pour les sous-expressions suivantes :

  • s.find("even")
  • s.find(" don't")

Leur ordre d'évaluation est indéterminé par rapport à :

  • s.replace(0, 4 , "")

Cela signifie que les appels de recherche peuvent être évalués avant ou après l'appel de remplacement, affectant la longueur de s et modifiant par conséquent les résultats des appels de recherche.

Illustration avec la fonction de recherche personnalisée

Pour démontrer cette ambiguïté, une version modifiée du code utilise une fonction my_find personnalisée qui rapporte la position des chaînes de recherche dans chaque évaluation de sous-expression :

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

L'exécution de ce code avec différents compilateurs donne des résultats différents selon l'ordre d'évaluation :

  • Clang : my_find est évalué pour "même" avant d'être évalué pour "ne pas faire", ce qui donne le résultat correct.
  • GCC : my_find est évalué pour "ne pas faire" avant d'être évalué pour "même", ce qui conduit à un résultat incorrect .

Modifications C 17

La norme C 17 (p0145r3) introduit des améliorations aux règles d'ordre d'évaluation des expressions pour lever cette ambiguïté. Il renforce l'ordre d'évaluation des expressions postfixées et de leur liste d'expressions comme suit :

  • L'expression postfixée est séquencée avant chaque expression de la liste d'expressions et tout argument par défaut.

Cela garantit que les appels de méthode chaînés sont évalués dans l'ordre attendu, résolvant ainsi ce comportement non défini en C 17.

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