Bjarne Stroustrup의 코드에서 std::string의 연결 표현식이 정의되지 않은 동작을 나타냅니까?
Bjarne Stroustrup의 "The C 프로그래밍 언어" 4판 , 코드 조각은 std::string의 대체 메소드를 사용한 연결을 예시합니다:
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");
}
그러나 이 코드는 정의되지 않은 동작을 호출하는 대신 지정되지 않은 동작을 나타냅니다.
이 지정되지 않은 동작의 이유는 평가 순서에 있습니다. 연결된 함수 호출의 하위 표현식. 이 경우 s.find 함수 호출은 첫 번째 s.replace 호출 전후에 평가되어 결과 문자열의 길이를 변경하고 후속 find 호출 결과에 영향을 줍니다.
질문의 예는 다음을 보여줍니다. 다른 컴파일러(clang, gcc)로 평가할 때 다양한 평가 순서로 인해 다른 결과가 얻어집니다.
세부정보
함수 인수에는 지정되지 않은 평가 순서가 있으며, 반면 함수 호출 연결은 각 함수 호출에 대해 왼쪽에서 오른쪽으로 평가 순서를 도입하고 각 호출의 인수는 해당 특정 함수 호출과 관련하여 앞에만 순서가 지정됩니다.
예제에서, 이러한 불확정성은 s.replace(0, 4, "")와 관련하여 s.find("even") 및 s.find(" don't")를 평가할 때 발생합니다.추가 하위 무시 -표현식 분석, 평가 단계 순서 및 상호 의존성은 다음과 같이 설명할 수 있습니다.1단계: s.replace(0, 4, "") // A 2단계: s.find("even") // B 3단계: s.replace(B, 4, "only") // C 4단계: s.find("하지 마세요") // D 5단계: s.replace(D, 6, "") // EStep 1: s.replace(0, 4, "") // A Step 2: s.find("even") // B Step 3: s.replace(B, 4, "only") // C Step 4: s.find("don't") // D Step 5: s.replace(D, 6, "") // EA가 B보다 먼저 시퀀스되고 B가 다시 C보다 먼저 시퀀스되는 반면, 사이에는
시퀀싱 관계가 없습니다. A에 대해 B와 D. 결과적으로 D는 A 이전이나 이후에 평가될 수 있으며, 선택한 순서에 따라 다른 결과로 이어집니다.
C 17 변경 사항
C 17 표준은 후위 표현식과 해당 표현식 목록에 대한 평가 규칙의 순서를 강화하여 문제의 코드에 잘 지정된 동작을 제공합니다. 순서는 다음과 같습니다:부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3