Does Chaining STL Methods in C Preserve Evaluation Order?
In Bjarne Stroustrup's "The C Programming Language" 4th edition, the following code snippet exemplifies method chaining:
<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>
This code evaluates statements from left to right, altering the string s incrementally. However, the behavior of this expression is ambiguous depending on the compiler used:
Unveiling the Unspecified Behavior
The code exhibits unspecified behavior because of the indeterminate order of evaluation of subexpressions, despite not invoking undefined behavior. The crux of the issue lies in the evaluation order of function arguments within chained function calls.
Specifically, for the following sub-expressions:
Their evaluation order is indeterminate with respect to:
This means that the find calls can be evaluated before or after the replace call, affecting the length of s and consequently altering the results of the find calls.
Illustration with Custom Find Function
To demonstrate this ambiguity, a modified version of the code uses a custom my_find function that reports the position of the search strings in each sub-expression evaluation:
<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>
Running this code with different compilers yields different results depending on the evaluation order:
C 17 Changes
The C 17 standard (p0145r3) introduces refinements to the expression evaluation order rules to address this ambiguity. It strengthens the order of evaluation for postfix-expressions and their expression-list as follows:
This ensures that chained method calls evaluate in the expected order, resolving this undefined behavior in C 17.
The above is the detailed content of Does STL Method Chaining Preserve Evaluation Order in C ?. For more information, please follow other related articles on the PHP Chinese website!