> 백엔드 개발 > C++ > 본문

Stroustrup의 \'C 프로그래밍 언어\' 4판의 C 코드 연결 방법 호출에 잘 정의된 동작이 있습니까?

Patricia Arquette
풀어 주다: 2024-10-23 17:44:02
원래의
966명이 탐색했습니다.

Does the C   Code Chaining Method Calls in Stroustrup's

"C 프로그래밍 언어" 4판 섹션 36.3.6의 이 코드가 잘 정의된 동작을 가지고 있습니까?

문제의 코드는 연결 메서드 호출을 보여줍니다.

<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>
로그인 후 복사

그러나 Assert는 Clang에서 전달되는 동안 GCC 및 Visual Studio와 같은 특정 컴파일러에서는 실패합니다.

문제

이 코드는 함수 인수가 순서 없이 평가되므로 하위 표현식 평가 순서가 지정되지 않습니다. 연결된 함수 호출은 각 함수 호출에 대해 왼쪽에서 오른쪽으로 평가 순서를 도입하지만 각 호출의 인수는 자신이 속한 멤버 함수 호출 이전에만 순서가 지정됩니다.

코드에서 하위 표현식 s .find("even") 및 s.find(" don't")는 s.replace(0, 4, "")에 대해 불확실하게 순서가 지정됩니다. 평가 순서에 따라 잠재적 부작용으로 인해 결과가 달라질 수 있습니다.

지정되지 않은 평가 순서

코드는 다음과 같이 나눌 수 있습니다.

s.replace(0, 4, "" )                  // A
    .replace( s.find( "even" ), 4, "only" )    // B
        .replace( s.find( " don't" ), 6, "" );   // C
로그인 후 복사

A는 B보다 먼저 순서가 지정되고 B는 C보다 먼저 순서가 지정됩니다. 항목 1-9는 다음 관계를 제외하고 서로에 대해 불확정적으로 순서가 지정됩니다.

  • 1-3은 B보다 먼저 순서가 지정됩니다
  • 4-6은 C 이전에 배열됩니다
  • 7-9는 D 이전에 배열됩니다

그러나 B에 대해서는 4-9가 불확실하게 배열됩니다. 이 평가 선택 B에 대한 4와 7의 순서는 Clang과 GCC 사이의 다른 결과를 설명합니다.

평가 순서 테스트

테스트 프로그램을 사용하여 평가 순서를 확인할 수 있습니다.

<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>
로그인 후 복사

결과는 4와 7에 대한 B의 평가 순서에 따라 다릅니다.

C 17 변경 사항

C 17은 이 코드에 잘 정의된 동작을 제공하는 p0145r3의 변경 사항을 도입했습니다. 후위 표현식 및 해당 표현식 목록에 대한 평가 규칙의 순서를 강화합니다. 특히 이 변경은 함수가 입력되기 전에 표현식 목록의 모든 표현식이 순서대로 지정되도록 지정합니다. 이렇게 하면 코드가 개별 하위 표현식의 평가 순서에 관계없이 동일한 결과를 생성합니다.

위 내용은 Stroustrup의 \'C 프로그래밍 언어\' 4판의 C 코드 연결 방법 호출에 잘 정의된 동작이 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!