Home  >  Article  >  Backend Development  >  Does the C Code Chaining Method Calls in Stroustrup\'s \"The C Programming Language\" 4th Edition Have Well-Defined Behavior?

Does the C Code Chaining Method Calls in Stroustrup\'s \"The C Programming Language\" 4th Edition Have Well-Defined Behavior?

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

Does the C   Code Chaining Method Calls in Stroustrup's

Does this Code from "The C Programming Language" 4th Edition Section 36.3.6 Have Well-Defined Behavior?

The code in question demonstrates chaining method calls:

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

However, the assert fails in certain compilers like GCC and Visual Studio, while it passes in Clang.

The Issue

This code exhibits unspecified behavior due to the unspecified order of evaluating sub-expressions, as function arguments are evaluated in an unsequenced order. Chained function calls introduce a left-to-right evaluation order for each function call, but the arguments of each call are only sequenced before the member function call they belong to.

In the code, the sub-expressions s.find("even") and s.find(" don't") are indeterminately sequenced with respect to s.replace(0, 4, ""). Depending on the order of evaluation, the result can vary due to potential side effects.

Unspecified Order of Evaluation

The code can be broken down as follows:

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

A is sequenced before B, which is sequenced before C. Items 1-9 are indeterminately sequenced with respect to each other, except for the following relationships:

  • 1-3 are sequenced before B
  • 4-6 are sequenced before C
  • 7-9 are sequenced before D

However, 4-9 are indeterminately sequenced with respect to B. This choice of evaluation order for 4 and 7 with respect to B explains the different results between Clang and GCC.

Testing Evaluation Order

A test program can be used to demonstrate the evaluation order:

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

The results differ based on the evaluation order of B with respect to 4 and 7.

C 17 Changes

C 17 introduced changes in p0145r3 that give this code well-defined behavior by strengthening the order of evaluation rules for postfix expressions and their expression lists. Specifically, this change specifies that all expressions in the expression list are sequenced before the function is entered. This ensures that the code will produce the same result regardless of the evaluation order of the individual sub-expressions.

The above is the detailed content of Does the C Code Chaining Method Calls in Stroustrup\'s \"The C Programming Language\" 4th Edition Have Well-Defined Behavior?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn