zero_initialization — 0 초기화
zero_initialization — 0 초기화 (Zero-initialization)
**0 초기화(zero-initialization)**는 객체의 초기 값을 0으로 설정하는 초기화예요. 언어에 전용 문법은 없고, 정적/스레드 로컬 변수나 값 초기화의 일부로 수행돼요.
static int n; 같은 전역 변수는 자동으로 0 초기화되어 0 값을 가져요. 포인터라면 널 포인터 값으로 초기화돼요.
출처: cppreference
본문
0 초기화는 객체의 초기 값을 0으로 설정해요.
문법 (Syntax)
참고: 이것은 0 초기화의 문법이 아니에요. 0 초기화에는 언어에 전용 문법이 없어요. 아래는 0 초기화를 수행할 수 있는 다른 종류의 초기화 예시예요.
static T object ;
T () ;
T t = {} ;
T {} ;
CharT array[n] = " short-sequence ";
설명 (Explanation)
0 초기화는 다음 상황에서 수행돼요.
- 상수 초기화를 받지 않는 정적 또는 스레드 로컬 저장 기간의 모든 이름 있는 변수에 대해, 다른 초기화 전에
- 비클래스 타입과 생성자가 없는 값 초기화된 클래스 타입 멤버의 값 초기화 시퀀스의 일부로 (초기화자를 제공받지 않은 애그리거트 요소의 값 초기화 포함)
- 어떤 문자 타입의 배열이 너무 짧은 문자열 리터럴로 초기화될 때, 배열의 나머지 부분이 0 초기화될 때
0 초기화의 효과
T가 스칼라 타입이면, 정수 리터럴0(영)을 명시적으로T로 변환해 얻은 값으로 객체가 초기화돼요.T가 비유니온 클래스 타입이면:- 모든 패딩 비트가 0 비트로 초기화
- 각 비정적 데이터 멤버가 0 초기화
- 각 비가상 기반 클래스 부분 객체가 0 초기화
- 객체가 기반 클래스 부분 객체가 아니면 각 가상 기반 클래스 부분 객체가 0 초기화
T가 유니언 타입이면:- 모든 패딩 비트가 0 비트로 초기화
- 객체의 첫 번째 비정적 이름 있는 데이터 멤버가 0 초기화
T가 배열 타입이면 각 요소가 0 초기화T가 참조 타입이면 아무것도 하지 않음
노트 (Notes)
비로컬 초기화에서 설명했듯, 상수 초기화되지 않는 정적·스레드 로컬 변수는 다른 초기화가 일어나기 전에 0 초기화돼요. 비클래스 비로컬 변수의 정의에 초기화자가 없으면 기본 초기화는 아무것도 하지 않아, 앞선 0 초기화의 결과를 그대로 두어요.
0 초기화된 포인터는 그 타입의 널 포인터 값이에요. 널 포인터의 값이 정수 0이 아니어도 마찬가지예요.
예제 (Example)
#include <iostream>
#include <string>
struct A
{
int a, b, c;
};
double f[3]; // 세 개의 0.0 으로 0 초기화
int* p; // 널 포인터 값으로 0 초기화
// (값이 정수 0 이 아니어도)
std::string s; // 불확정 값으로 0 초기화된 뒤,
// std::string 기본 생성자로 "" 로 기본 초기화
int main(int argc, char*[])
{
delete p; // 널 포인터 삭제는 안전
static int n = argc; // 0 으로 0 초기화된 뒤 argc 로 복사 초기화
std::cout << "n = " << n << '\n';
A a = A(); // A a{}; 또는 A a = {}; 와 같은 효과
std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
}
출력:
n = 1
a = {0 0 0}
static int n = argc;는 먼저 0 초기화되어 0이 된 뒤, 그 다음에 argc로 복사 초기화돼요. A a = A();는 A의 멤버들이 0 초기화되어 a = {0 0 0}이 돼요.