Spec-Zone.ru › C++

Нулевая инициализация

Устанавливает начальное значение объекта в ноль.

Синтаксис

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

static T object ; (1)
T () ;

T t = {} ;

T {} ; (с C++11)

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

Объяснение

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

1) Для каждой именованной переменной со статической или локальной(с C++11) продолжительностью хранения, которая не подвергается постоянной инициализации, перед любой другой инициализацией.
2) В качестве части последовательности инициализации значением для типов, не являющихся классами, и для членов типов классов, инициализируемых значением, которые не имеют конструкторов, включая инициализацию значением элементов агрегатов, для которых не предоставлены инициализаторы.
3) При инициализации массива любого типа символов строковым литералом, который слишком короткий, остальная часть массива инициализируется нулями.

Эффекты нулевой инициализации:

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

Примечания

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

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

Пример

#include <iostream>
#include <string>
 
struct A
{
    int a, b, c;
};
 
double f[3];   // zero-initialized to three 0.0's
 
int* p;        // zero-initialized to null pointer value
               // (even if the value is not integral 0)
 
std::string s; // zero-initialized to indeterminate value, then
               // default-initialized to "" by the std::string default constructor
 
int main(int argc, char*[])
{
    delete p; // safe to delete a null pointer
 
    static int n = argc; // zero-initialized to 0 then copy-initialized to argc
    std::cout << "n = " << n << '\n';
 
    A a = A(); // the effect is same as: A a{}; or 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 не было ясно, применяется ли нулевая инициализация к безымянным битовым полям она применяется (все биты заполнения
инициализируются нулевыми битами)

См. также

  • конструктор
  • копирование присваивания
  • конструктор по умолчанию
  • инициализация
    • агрегированная инициализация
    • постоянная инициализация
    • инициализация копированием
    • инициализация по умолчанию
    • прямая инициализация
    • инициализация списком
    • инициализация значением
  • присваивание перемещением
  • new

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/zero_initialization

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API