> 백엔드 개발 > C++ > \'C 프로그래밍 언어\'의 함수 체이닝이 지정되지 않은 동작을 나타냅니까?

\'C 프로그래밍 언어\'의 함수 체이닝이 지정되지 않은 동작을 나타냅니까?

Barbara Streisand
풀어 주다: 2024-10-23 18:19:25
원래의
457명이 탐색했습니다.

Does Function Chaining in

"C 프로그래밍 언어"의 코드 조각이 정의되지 않은 동작을 나타냅니까?

"의 4판에서 Bjarne Stroustrup이 제공한 문제의 C 코드 C 프로그래밍 언어"는 문자열을 수정하기 위해 함수 체이닝을 사용합니다.

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

이 코드는 문자열 s를 변경하기 위한 교체() 작업의 체이닝을 보여줍니다. 그러나 이 코드는 GCC, Visual Studio, Clang과 같은 다양한 컴파일러에서 서로 다른 동작을 나타내는 것으로 관찰되었습니다.

분석

코드가 간단해 보이지만 지정되지 않은 순서가 포함되어 있습니다. 특히 함수 호출과 관련된 하위 표현식에 대한 평가입니다. 정의되지 않은 동작을 호출하지는 않지만(모든 부작용은 함수 호출 내에서 발생하므로) 지정되지 않은 동작을 나타냅니다.

핵심 문제는 s.find( "even") 및 s.find(" don't")는 명시적으로 정의되지 않습니다. 이러한 하위 표현식은 초기 s.replace(0, 4, "") 호출 전후에 평가될 수 있으며 이는 결과에 영향을 미칠 수 있습니다.

코드 조각에 대한 평가 순서를 살펴보면 다음과 같습니다.

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

다음 하위 표현식이 불확실하게 순서가 지정되어 있음을 알 수 있습니다(괄호 안의 숫자로 표시).

  • s.replace(0, 4, "") (1)
  • s.find("even") (2)
  • s.replace(s.find("even"), 4, "only") (3)
  • s.find(" 하지 마세요") (4)
  • s.replace(s.find(" 하지 마세요"), 6, "") (5)

각 괄호 쌍 안의 표현식은 순서가 지정되어 있지만(예: 2가 3보다 앞선다) 서로 다른 순서로 평가될 수 있습니다. 특히, 불확정성은 식 1과 2 사이뿐 아니라 식 1과 4 사이에도 있습니다.

컴파일러 차이점

컴파일러 동작에서 관찰된 불일치는 각각이 선택한 서로 다른 평가 순서에 기인할 수 있습니다. 컴파일러. 어떤 경우에는 교체() 호출이 예상된 동작을 초래하는 방식으로 평가되는 반면, 다른 경우에는 평가 순서가 예상치 못한 방식으로 문자열을 변경합니다.

설명하려면 다음을 고려하세요.

  • Clang과 같은 일부 구현에서는 교체(0, 4, "")가 find("even") 및 find(" don't")보다 먼저 평가됩니다. 이렇게 하면 후속 교체 호출이 수정된 문자열에서 작동하여 올바른 결과를 얻을 수 있습니다.
  • GCC 및 Visual Studio와 같은 다른 구현에서는 find("even") 및 find(" don't") 대체(0, 4, "") 전에 평가될 수 있습니다. 찾기 호출이 수정되지 않은 원본 문자열에서 작동하여 잠재적으로 의도한 것과 다른 위치를 찾을 수 있기 때문에 잘못된 결과가 발생할 수 있습니다.

지정된 동작과 지정되지 않은 동작

다음에 유의하는 것이 중요합니다. 이 코드는 정의되지 않은 동작을 호출하지 않습니다. 정의되지 않은 동작에는 일반적으로 초기화되지 않은 변수에 액세스하거나 해당 범위 외부의 메모리에 액세스하려고 시도하는 것이 포함됩니다. 이 경우 모든 부작용은 함수 호출 내에서 발생하며 코드는 잘못된 메모리 위치에 액세스하지 않습니다.

그러나 코드는 지정되지 않은 동작을 나타냅니다. 하위 표현식의 평가는 C 표준에 의해 정의되지 않습니다. 이로 인해 서로 다른 컴파일러 또는 동일한 프로그램의 서로 다른 실행에서 서로 다른 결과가 발생할 수 있습니다.

제안된 변경 사항

C 표준 위원회는 이 문제를 인식하고 식 평가 순서를 개선하기 위한 변경 사항을 제안했습니다. 관용적 C . C 20의 [expr.call]p5에 대한 제안된 변경 사항은 "후위 표현식이 표현식 목록 및 기본 인수의 각 표현식 앞에 순서대로 지정됩니다"라고 지정하여 이 코드에서 지정되지 않은 동작을 제거합니다.

위 내용은 \'C 프로그래밍 언어\'의 함수 체이닝이 지정되지 않은 동작을 나타냅니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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