Namespaces
Variants

Zero-initialization

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

객체의 초기값을 0으로 설정합니다.

목차

구문

이것이 제로 초기화를 위한 구문이 아니라는 점에 유의하십시오. 제로 초기화는 언어에서 전용 구문을 가지고 있지 않습니다. 이들은 제로 초기화를 수행할 수 있는 다른 유형의 초기화 예시입니다.

static T object ; (1)
T () ;

T t = {} ;

T {} ; (C++11 이후)

(2)
CharT array [ n ] = " short-sequence "; (3)

설명

제로 초기화는 다음과 같은 상황에서 수행됩니다:

1) 정적 또는 스레드-지역 (C++11부터) 저장 기간 을 가지며 상수 초기화 대상이 아닌 모든 명명된 변수에 대해, 다른 어떤 초기화보다 먼저 수행됩니다.
2) 값 초기화 시퀀스의 일부로서, 비클래스 타입과 생성자가 없는 값 초기화된 클래스 타입의 멤버들에 대해, 그리고 제공된 초기화자가 없는 aggregates 의 요소들에 대한 값 초기화를 포함합니다.
3) 임의의 character type 배열이 너무 짧은 문자열 리터럴로 initialized with a string literal 될 때, 배열의 나머지 부분은 zero-initialized 됩니다.

제로 초기화의 효과는 다음과 같습니다:

  • 만약 T scalar type 인 경우, 객체는 정수 리터럴 0 (영)을 T 명시적으로 변환 하여 얻은 값으로 초기화됩니다.
  • 만약 T 가 non-union 클래스 타입인 경우:
  • 만약 T 가 union 타입인 경우:
  • 모든 패딩 비트는 0 비트로 초기화되며,
  • 객체의 첫 번째 비정적 명명된 데이터 멤버는 0으로 초기화됩니다.
  • 만약 T 가 배열 타입인 경우, 각 요소는 제로 초기화됩니다.
  • 만약 T 가 참조 타입인 경우, 아무 작업도 수행되지 않습니다.

참고 사항

비지역 초기화 에서 설명된 바와 같이, 상수 초기화되지 않은 정적 및 스레드 지역 (C++11부터) 변수들은 다른 어떤 초기화보다 먼저 영(0) 초기화됩니다. 비클래스 비지역 변수의 정의에 초기화자가 없는 경우, 기본 초기화는 아무 작업도 수행하지 않으며 이전의 영 초기화 결과를 수정하지 않고 그대로 둡니다.

영으로 초기화된 포인터는 널 포인터 값이 정수형 0이 아닌 경우에도 해당 타입의 널 포인터 값입니다.

예제

#include <iostream>
#include <string>
struct A
{
    int a, b, c;
};
double f[3];   // 3개의 0.0으로 zero-initialized
int* p;        // null pointer 값으로 zero-initialized
               // (값이 integral 0이 아닌 경우에도)
std::string s; // indeterminate 값으로 zero-initialized된 후,
               // std::string 기본 생성자에 의해 ""로 default-initialized
int main(int argc, char*[])
{
    delete p; // null pointer 삭제는 안전함
    static int n = argc; // 0으로 zero-initialized된 후 argc로 copy-initialized
    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}

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 277 C++98 널 포인터 상수가 아닌 값 0의 비상수
표현식으로 포인터를 초기화할 수 있었음
값 0의 정수형 상수
표현식으로 초기화해야 함
CWG 694 C++98 클래스 타입에 대한 제로 초기화 시 패딩을 무시함 패딩은 제로 비트로 초기화됨
CWG 903 C++98 스칼라 타입에 대한 제로 초기화 시 초기값을
값 0의 정수형 상수 표현식에서 변환된 값으로 설정함
객체는 정수 리터럴 0 에서
변환된 값으로 초기화됨
CWG 2026 C++98 상수 초기화보다 항상 먼저 제로 초기화가
발생하도록 명시됨
상수 초기화가 적용되는 경우
제로 초기화를 수행하지 않음
CWG 2196 C++98 클래스 타입에 대한 제로 초기화 시
기본 클래스 서브오브젝트를 무시함
기본 클래스 서브오브젝트도
제로 초기화됨
CWG 2253 C++98 이름 없는 비트 필드에 제로 초기화가
적용되는지 불명확했음
적용됨 (모든 패딩 비트가
제로 비트로 초기화됨)

참고 항목