Zero-initialization
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
|
(2) | ||||||||
CharT
array
[
n
]
=
"
short-sequence
";
|
(3) | ||||||||
Explicación
La inicialización a cero se realiza en las siguientes situaciones:
Los efectos de la inicialización a cero son:
-
Si
Tes un tipo escalar, el objeto se inicializa al valor obtenido mediante la conversión explícita del literal entero 0 (cero) aT. -
Si
Tes un tipo de clase no unión:
-
- todos los bits de relleno se inicializan a bits cero,
- cada miembro de datos no estático se inicializa a cero,
- cada subobjeto de clase base no virtual se inicializa a cero, y
- si el objeto no es un subobjeto de clase base, cada subobjeto de clase base virtual se inicializa a cero.
-
Si
Tes 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
Tes tipo array, cada elemento es inicializado a cero. -
Si
Tes 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) |