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 — это std::meta::info, объект инициализируется нулевым значением отражения.
(начиная с C++26)
  • Если 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/cpp/language/zero_initialization

Spec-Zone.ru

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