default_initialization — 기본 초기화

default_initialization — 기본 초기화 (Default-initialization)

**기본 초기화(default-initialization)**는 객체가 초기화자 없이 생성될 때 수행되는 초기화예요. T obj;처럼 선언하거나 초기화자 없는 new로 만들 때 적용돼요.

클래스 타입이라면 기본 생성자가 호출되고, 기본 생성자가 없다면 아무 초기화도 수행되지 않아요. 초기화자 없이 변수를 선언하면 그 값이 정의되지 않는 경우가 많다는 점을 이해하는 게 중요해요.

출처: cppreference

본문

기본 초기화는 객체가 초기화자 없이 생성될 때 수행되는 초기화예요.

문법 (Syntax)

T object;
new T

설명 (Explanation)

기본 초기화는 세 가지 상황에서 수행돼요.

  1. 자동, 정적, 스레드 로컬 저장 기간의 변수가 초기화자 없이 선언될 때
  2. 초기화자 없이 new 표현식으로 동적 저장 기간 객체가 생성될 때
  3. 기반 클래스나 비정적 데이터 멤버가 생성자 초기화 목록에 언급되지 않고 그 생성자가 호출될 때

기본 초기화의 효과

  • T가 (가능하면 cv 한정된) 비-POD 클래스 타입이면, 생성자들을 고려해 빈 인자 목록으로 과부하 해석을 적용해요. 선택된 생성자(기본 생성자 중 하나)가 새 객체의 초기 값을 제공하기 위해 호출돼요.
  • T가 배열 타입이면, 배열의 모든 요소가 기본 초기화돼요.
  • 그 외에는 어떤 초기화도 수행되지 않아요.

const 객체의 기본 초기화

const 한정 타입 T의 객체 기본 초기화를 요청하면, T는 오직 const-default-constructible 타입이어야 해요.

타입 T가 const-default-constructible이 되려면 다음 중 하나가 성립해야 해요.

  • Tstd::meta::info 또는 std::nullptr_t
  • T의 기본 초기화가 (기반에서 상속받지 않은) T의 사용자 제공 생성자를 호출
  • T가 클래스 타입으로, 각 직접 비변형 비정적 데이터 멤버가 기본 멤버 초기화자를 가지거나 const-default-constructible 타입이고, 유니언이면 정확히 하나의 변형 멤버가 기본 멤버 초기화자를 가지며, 각 잠재적으로 구성될 기반 클래스가 const-default-constructible인 경우
  • T가 const-default-initializable 타입의 배열

불확정 값과 오류 값

C++26까지, 자동 또는 동적 저장 기간 객체의 저장 공간을 얻을 때 그 객체는 **불확정 값(indeterminate value)**을 가져요. 객체에 어떤 초기화도 수행되지 않으면, 그 값이 대체될 때까지 불확정 값을 유지해요.

불확정 값을 산출하는 평가는 동작이 정의되지 않아요. C++26부터 오류 값(erroneous value)을 산출하면 그 동작은 오류(erroneous)예요.

특수한 경우

std::byte, unsigned char, (기반 타입이 unsigned char인) char 타입은 uninitialized-friendly예요. 이 타입의 불확정/오류 값에 대해, 일부 조건부 표현식·쉼표 표현식·정수 변환·폐기 값 표현식 등 제한된 상황에서는 잘 정의된 동작을 가질 수 있어요.

예제 (Example)

#include <string>

struct T1 { int mem; };

struct T2
{
    int mem;
    T2() {} // "mem" 은 초기화 목록에 없음
};

int n; // 정적 비클래스, 두 단계 초기화 수행:
       // 1) 0 초기화로 n 을 0 으로
       // 2) 기본 초기화는 아무것도 하지 않아 n 을 0 으로 둠

int main()
{
    [[maybe_unused]]
    int n;            // 비클래스, 값은 불확정
    std::string s;    // 클래스, 기본 생성자 호출, 값은 ""
    std::string a[2]; // 배열, 요소들을 기본 초기화, 값은 {"", ""}
//  int& r;           // 오류: 참조
//  const int n;      // 오류: const 비클래스
//  const T1 t1;      // 오류: 암시적 기본 생성자의 const 클래스
    [[maybe_unused]]
    T1 t1;            // 클래스, 암시적 기본 생성자 호출
    const T2 t2;      // const 클래스, 사용자 제공 기본 생성자 호출
                      // t2.mem 은 기본 초기화됨
}

int n;은 값이 불확정이고, std::string s;는 기본 생성자를 호출해 ""가 돼요. const T1 t1;은 암시적 기본 생성자를 가진 const 클래스라서 오류가 나지만, const T2 t2;는 사용자 제공 기본 생성자가 있어서 허용돼요.

더 알아보기 (Learn more)

cppreference