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

Устанавливает начальное значение объекта равным нулю.

Содержание

Синтаксис

Обратите внимание, что это не синтаксис для zero-initialization, который не имеет специального синтаксиса в языке. Это примеры других типов инициализации, которые могут выполнять zero-initialization.

static T object ; (1)
T () ;

T t = {} ;

T {} ; (начиная с C++11)

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

Объяснение

Обнуляющая инициализация выполняется в следующих ситуациях:

1) Для каждой именованной переменной со статической или thread-local (начиная с C++11) storage duration , которая не подлежит constant initialization , до любой другой инициализации.
2) В рамках последовательности value-initialization для неклассовых типов и для членов инициализируемых значением классовых типов, не имеющих конструкторов, включая инициализацию значением элементов aggregates , для которых не предоставлены инициализаторы.
3) Когда массив любого character type инициализируется string literal , который слишком короткий, остальная часть массива заполняется нулями.

Эффекты от инициализации нулями:

  • Если T является типом объединения:
  • все биты заполнения инициализируются нулевыми битами, и
  • первый нестатический именованный элемент данных объекта инициализируется нулями.
  • Если T является типом массива, каждый элемент инициализируется нулями.
  • Если T является ссылочным типом, ничего не выполняется.

Примечания

Как описано в разделе инициализация нелокальных переменных , статические и thread-local (since C++11) переменные, которые не являются константно-инициализированными, проходят zero-инициализацию до выполнения любой другой инициализации. Если определение неклассовой нелокальной переменной не имеет инициализатора, то default-инициализация не выполняет никаких действий, оставляя результат предыдущего zero-инициализации неизменным.

Обнуленный указатель является нулевым указателем своего типа, даже если значение нулевого указателя не является целочисленным нулем.

Пример

#include <iostream>
#include <string>
struct A
{
    int a, b, c;
};
double f[3];   // инициализированы нулями до трёх 0.0
int* p;        // инициализирован нулём как нулевой указатель
               // (даже если значение не является целочисленным 0)
std::string s; // инициализирован неопределённым значением, затем
               // инициализирован по умолчанию как "" конструктором std::string по умолчанию
int main(int argc, char*[])
{
    delete p; // безопасно удалить нулевой указатель
    static int n = argc; // инициализирован нулём, затем копирующая инициализация значением 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}

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам 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 было неясно, применяется ли обнуляющая инициализация
к безымянным битовым полям
применяется (все биты заполнения
инициализируются нулевыми битами)

Смотрите также