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

Establece el valor inicial de un objeto en cero.

Contenidos

Sintaxis

Tenga en cuenta que esta no es la sintaxis para la inicialización a cero, que no tiene una sintaxis dedicada en el lenguaje. Estos son ejemplos de otros tipos de inicializaciones, que podrían realizar inicialización a cero.

static T object ; (1)
T () ;

T t = {} ;

T {} ; (desde C++11)

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

Explicación

La inicialización a cero se realiza en las siguientes situaciones:

1) Para cada variable nombrada con duración de almacenamiento estática o thread-local (desde C++11) storage duration que no está sujeta a constant initialization , antes de cualquier otra inicialización.
2) Como parte de la secuencia de value-initialization para tipos no-clase y para miembros de tipos clase value-initialized que no tienen constructores, incluyendo la value initialization de elementos de aggregates para los cuales no se proporcionan inicializadores.
3) Cuando un array de cualquier character type es initialized with a string literal que es demasiado corto, el resto del array es zero-initialized.

Los efectos de la inicialización a cero son:

  • Si T es un tipo escalar, el objeto se inicializa al valor obtenido mediante la conversión explícita del literal entero 0 (cero) a T .
  • Si T es un tipo de clase no unión:
  • Si T es un tipo unión:
  • todos los bits de relleno se inicializan a bits cero, y
  • el primer miembro de datos con nombre no estático del objeto se inicializa a cero.
  • Si T es tipo array, cada elemento es inicializado a cero.
  • Si T es tipo referencia, no se hace nada.

Notas

Como se describe en inicialización no local , las variables estáticas y thread-local (desde C++11) que no están constant-initialized son zero-initialized antes de que ocurra cualquier otra inicialización. Si la definición de una variable no local que no es de clase no tiene inicializador, entonces la default initialization no hace nada, dejando el resultado de la zero-initialization anterior sin modificar.

Un puntero inicializado a cero es el valor de puntero nulo de su tipo, incluso si el valor del puntero nulo no es cero integral.

Ejemplo

#include <iostream>
#include <string>
struct A
{
    int a, b, c;
};
double f[3];   // inicializado a cero como tres 0.0
int* p;        // inicializado a cero como valor de puntero nulo
               // (incluso si el valor no es 0 integral)
std::string s; // inicializado a cero a valor indeterminado, luego
               // inicializado por defecto a "" por el constructor por defecto de std::string
int main(int argc, char*[])
{
    delete p; // seguro eliminar un puntero nulo
    static int n = argc; // inicializado a cero a 0 luego inicializado por copia a argc
    std::cout << "n = " << n << '\n';
    A a = A(); // el efecto es igual que: A a{}; o A a = {};
    std::cout << "a = {" << a.a << ' ' << a.b << ' ' << a.c << "}\n";
}

Salida posible:

n = 1
a = {0 0 0}

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 277 C++98 los punteros podían inicializarse con una expresión
no constante de valor 0, que no es una constante de puntero nulo
debe inicializarse con una expresión constante
entera de valor 0
CWG 694 C++98 la inicialización a cero para tipos clase ignoraba el relleno el relleno se inicializa con bits cero
CWG 903 C++98 la inicialización a cero para tipos escalares establecía el valor inicial al valor
convertido desde una expresión constante entera con valor 0
el objeto se inicializa al valor
convertido desde el literal entero 0
CWG 2026 C++98 la inicialización a cero se especificaba para ocurrir siempre
primero, incluso antes de la inicialización constante
no hay inicialización a cero si
aplica inicialización constante
CWG 2196 C++98 la inicialización a cero para tipos clase ignoraba los subobjetos de clase base también se inicializan a cero
CWG 2253 C++98 no estaba claro si la inicialización a cero
aplicaba a campos de bits sin nombre
aplica (todos los bits de relleno
se inicializan a bits cero)

Véase también