"의 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, "");
다음 하위 표현식이 불확실하게 순서가 지정되어 있음을 알 수 있습니다(괄호 안의 숫자로 표시).
각 괄호 쌍 안의 표현식은 순서가 지정되어 있지만(예: 2가 3보다 앞선다) 서로 다른 순서로 평가될 수 있습니다. 특히, 불확정성은 식 1과 2 사이뿐 아니라 식 1과 4 사이에도 있습니다.
컴파일러 동작에서 관찰된 불일치는 각각이 선택한 서로 다른 평가 순서에 기인할 수 있습니다. 컴파일러. 어떤 경우에는 교체() 호출이 예상된 동작을 초래하는 방식으로 평가되는 반면, 다른 경우에는 평가 순서가 예상치 못한 방식으로 문자열을 변경합니다.
설명하려면 다음을 고려하세요.
다음에 유의하는 것이 중요합니다. 이 코드는 정의되지 않은 동작을 호출하지 않습니다. 정의되지 않은 동작에는 일반적으로 초기화되지 않은 변수에 액세스하거나 해당 범위 외부의 메모리에 액세스하려고 시도하는 것이 포함됩니다. 이 경우 모든 부작용은 함수 호출 내에서 발생하며 코드는 잘못된 메모리 위치에 액세스하지 않습니다.
그러나 코드는 지정되지 않은 동작을 나타냅니다. 하위 표현식의 평가는 C 표준에 의해 정의되지 않습니다. 이로 인해 서로 다른 컴파일러 또는 동일한 프로그램의 서로 다른 실행에서 서로 다른 결과가 발생할 수 있습니다.
C 표준 위원회는 이 문제를 인식하고 식 평가 순서를 개선하기 위한 변경 사항을 제안했습니다. 관용적 C . C 20의 [expr.call]p5에 대한 제안된 변경 사항은 "후위 표현식이 표현식 목록 및 기본 인수의 각 표현식 앞에 순서대로 지정됩니다"라고 지정하여 이 코드에서 지정되지 않은 동작을 제거합니다.
위 내용은 \'C 프로그래밍 언어\'의 함수 체이닝이 지정되지 않은 동작을 나타냅니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!