40. 평가 순서(order of evaluation)와 시퀀싱, C++17의 규칙 변화

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// [주제] 평가 순서(order of evaluation)와 시퀀싱, C++17의 규칙 변화
//
// 아래 각 식/문장에서 부분식들이 어떤 순서로 평가되는지, 그리고 그 결과가
// (1) 잘 정의됨 (2) 미지정(unspecified) (3) 미정의(undefined) 중 무엇인지
// 예측하고, C++17 표준이 어떤 시퀀싱을 보장/비보장하는지 내부 동작으로
// 설명하라. (컴파일러마다/빌드마다 결과가 달라질 수 있는 곳을 지목)
//
// [과제]
//  1) f(g(), h()) 에서 g() 와 h() 의 상대적 호출 순서는?
//  2) i = i++ + 1; 의 정의 여부는? C++17 에서 달라졌는가?
//  3) a[i] = i++; 는? C++17 에서 달라졌는가?
//  4) std::cout << i << i++; 의 출력 순서 보장은? (연쇄 << 의 인자 평가)
//  5) obj.set(x).set(y) 같은 체이닝에서 x, y 평가와 set 호출의 순서는?
//  각 항목에 대해 "무엇이 sequenced-before 무엇인지"를 근거로 설명하라.

#include <iostream>

int i_global = 0;
int g() { std::cout << "g"; return 1; }
int h() { std::cout << "h"; return 2; }
int f(int a, int b) { return a + b; }

struct Builder {
    Builder& set(int) { return *this; }
};

int main() {
    // (1) 함수 인자 평가 순서
    int r = f(g(), h());
    (void)r;

    // (2) 같은 스칼라에 대한 읽기/쓰기
    int i = 0;
    i = i++ + 1;

    // (3) 첨자 대입
    int a[4] = {0,0,0,0};
    int k = 0;
    a[k] = k++;

    // (4) 연쇄 삽입 연산자의 인자 평가
    int j = 0;
    std::cout << j << j++ << "\n";

    // (5) 메서드 체이닝의 인자 평가
    int x = 0;
    Builder b;
    b.set(x++).set(x++);

    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.