6. 객체 생성/소멸 순서와 정적 초기화 (static init order fiasco)

난이도 중 해설 보기 →

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

결함 코드 · C++
// ============================================================================
// [언어 내부동작 문제] C++ - 객체 생성/소멸 순서와 정적 초기화
// ----------------------------------------------------------------------------
// 주제: 전역(정적 저장기간) 객체, 함수 지역 static, 함수 지역 자동 객체의 생성/소멸
//       시점과 순서. 그리고 "정적 초기화 순서 문제(static initialization order
//       fiasco)" 와 함수 지역 static(이른바 Meyers 싱글톤)의 관계.
//
// 과제(코드를 고치는 문제가 아니라, 출력과 내부 동작을 예측·설명하는 문제):
//   1) 이 프로그램의 전체 출력을 줄 단위로 정확히 예측하라(ctor/dtor 순서 포함).
//   2) g1, g2 는 언제(어느 시점에) 생성되는가? localStatic 의 static s 는 언제
//      생성되며, f() 를 두 번 불러도 몇 번 생성되는가? 그 근거(저장기간/초기화 규칙)를
//      설명하라.
//   3) 프로그램 종료 시 소멸 순서는 어떻게 정해지는가?
//   4) 서로 다른 번역 단위(translation unit)의 전역 객체끼리 초기화 순서에 의존하면
//      무슨 문제가 생기는가(static init order fiasco)? 함수 지역 static 으로 바꾸면
//      왜 그 문제가 사라지는가? C++11 이후 함수 지역 static 의 스레드 안전성도 함께
//      설명하라.
//   (먼저 직접 예측을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================

#include <iostream>

struct Tracer {
    const char* name;
    explicit Tracer(const char* n) : name(n) { std::cout << "ctor " << name << "\n"; }
    ~Tracer() { std::cout << "dtor " << name << "\n"; }
};

Tracer g1("g1");          // 전역 (정적 저장기간)
Tracer g2("g2");          // 전역 (정적 저장기간)

Tracer& localStatic() {
    static Tracer s("localStatic");   // 함수 지역 static
    return s;
}

void f() {
    Tracer t("f-local");              // 함수 지역 자동
    localStatic();
}

int main() {
    std::cout << "enter main\n";
    Tracer m("main-local");
    f();
    f();
    std::cout << "leave main\n";
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

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