L'expression de chaînage de std::string dans le code de Bjarne Stroustrup présente-t-elle un comportement non défini ?
Dans la 4e édition de "The C Programming Language" de Bjarne Stroustrup , un extrait de code illustre le chaînage à l'aide du remplacement de std::string méthode :
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");
}
Ce code présente cependant un comportement non spécifié au lieu d'invoquer un comportement non défini.
La raison de ce comportement non spécifié réside dans l'ordre d'évaluation, qui n'est pas spécifié pour sous-expressions d’appels de fonctions chaînés. Dans ce cas, les appels à la fonction s.find sont évalués avant ou après le premier appel à s.replace, modifiant la longueur de la chaîne résultante et affectant le résultat de l'appel find suivant.
L'exemple de la question démontre ceci : lorsqu'ils sont évalués par différents compilateurs (clang, gcc), des résultats différents sont obtenus en raison des différents ordres d'évaluation.
Détails
Fonction les arguments ont un ordre d'évaluation non spécifié, et bien que le chaînage des appels de fonction introduit un ordre d'évaluation de gauche à droite pour chaque appel de fonction, les arguments de chaque appel sont séquencés avant seulement par rapport à cet appel de fonction particulier.
Dans l'exemple, cette indétermination apparaît lors de l'évaluation de s.find("even") et s.find(" don't") par rapport à s.replace(0, 4, "").
En ignorant les autres répartitions des sous-expressions, la séquence des étapes d'évaluation et leur interdépendance peuvent être décrites comme suit :
Step 1: s.replace(0, 4, "") // A Step 2: s.find("even") // B Step 3: s.replace(B, 4, "only") // C Step 4: s.find("don't") // D Step 5: s.replace(D, 6, "") // E
Alors que A est séquencé avant B, qui à son tour est séquencé avant C, il n'y a aucune relation de séquençage entre B et D par rapport à A. En conséquence, D peut être évalué avant ou après A, conduisant à des résultats différents en fonction de la séquence choisie.
C 17 Modifications
La norme C 17 renforce l'ordre des règles d'évaluation des expressions postfixées et de leur liste d'expressions, donnant au code en question un comportement bien spécifié. Le séquençage est le suivant :
Par conséquent, dans C 17 et versions ultérieures, ce code sera toujours évalué correctement.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3