55. 복사 생략(copy elision)과 RVO/NRVO

난이도 중 해설 보기 →

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

결함 코드 · C++
// 주제: 복사 생략(copy elision)과 RVO/NRVO, C++17의 "보장된 복사 생략"
//
// 과제:
//   1) prvalue 반환(return T{};)에서 C++17이 보장하는 복사 생략이 무엇인지 설명하라.
//      C++14 이하의 "허용되지만 선택적"인 RVO와 무엇이 다른가?
//   2) 이름 있는 지역을 반환하는 NRVO 는 왜 여전히 "선택적"인가? 컴파일러가 NRVO를
//      적용하기 어려운 경우(예: 여러 반환 경로/조건부 반환)를 설명하라.
//   3) 아래 프로그램의 출력을 예측하라(g++/-O0 기준). 각 구간에서 ctor/copy/move/dtor 가
//      각각 몇 번 나오는지, 그 이유를 RVO/NRVO/이동으로 설명하라.

#include <cstdio>

struct Tracer {
    Tracer()                    { std::printf("ctor\n"); }
    Tracer(const Tracer&)       { std::printf("copy\n"); }
    Tracer(Tracer&&) noexcept   { std::printf("move\n"); }
    ~Tracer()                   { std::printf("dtor\n"); }
};

Tracer MakePrvalue() { return Tracer{}; }              // prvalue 반환
Tracer MakeNRVO()    { Tracer t; return t; }           // 이름 있는 지역 반환
Tracer MakeCond(bool b) { Tracer a, c; return b ? a : c; } // 조건부(삼항) 반환

int main() {
    std::printf("== prvalue ==\n");
    Tracer x = MakePrvalue();
    std::printf("== nrvo ==\n");
    Tracer y = MakeNRVO();
    std::printf("== cond ==\n");
    Tracer z = MakeCond(true);
    std::printf("== end ==\n");
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

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