c++ - off - recovery boot ubuntu
C++ Inicialización Cero (1)
Tengo problemas para entender cuándo y por qué exactamente un miembro de mi clase tiene cero inicialización de acuerdo con http://en.cppreference.com/w/cpp/language/zero_initialization .
Considere el siguiente programa de prueba:
#include <iostream>
#include <stdio.h>
class MyTest {
private:
const static unsigned int dimension = 8;
void (* myFunctions [dimension])();
public:
MyTest() {}
void print() {
for(unsigned int i=0; i < MyTest::dimension; i++) {
printf("myFunctions[%d] = %p/n", i, this->myFunctions[i]);
}
}
};
int main() {
//We declare and initialize an object on the stack
MyTest testObj = {};
testObj.print();
return 0;
}
Estoy declarando que una clase tiene una matriz de 8 punteros de función de la firma "void functionname ()". Cuando declaro e inicializo un objeto de la clase en main
como MyTest testObj = {};
o MyTest testObj;
, Esperaba que fuera cero inicializado, es decir, todos los punteros son punteros nulos.
Sin embargo, compilar con g ++ 5.3.0 en mi máquina con Windows 10 con g++ -m32 -o test -std=c++14 test.cpp && test
máquina da la salida:
myFunctions[0] = 76dd6b7d
myFunctions[1] = 00401950
myFunctions[2] = 0061ff94
myFunctions[3] = 004019ab
myFunctions[4] = 00401950
myFunctions[5] = 00000000
myFunctions[6] = 003cf000
myFunctions[7] = 00400080
Que parecen valores no inicializados de la pila ..
Si muevo la declaración del objeto fuera de main (como una variable global), imprime todos los ceros nuevamente.
Si he entendido cppreference correctamente, esto se debe a que tengo una variable variable con la duración del almacenamiento estático y, por lo tanto, está inicializado en cero. Inicializa mi tipo de clase mediante la inicialización cero de todos los miembros de datos no estáticos de la matriz de mi clase (es decir, las myFunctions
). Una matriz se inicializa mediante la inicialización cero de cada elemento de la misma, que, en mi caso de puntero de función, es un puntero nulo.
¿Por qué no inicializa a cero mi objeto en la pila cuando lo declaro con MyTest testObj = {};
?
El seguimiento
MyTest testObj = {};
no es una inicialización cero para MyTest
, sino que simplemente llama a su constructor predeterminado. La página cppreference explica por qué (el énfasis es mío):
Como parte de la secuencia de inicialización de valor para los tipos que no son de clase y para los miembros de los tipos de clase inicializados de valor que no tienen constructores , incluida la inicialización de valor de elementos de agregados para los cuales no se proporcionan inicializadores.
MyTest
es un tipo de clase, y tiene un constructor.
Definiendo el constructor con
MyTest() = default;
en su lugar , inicializará en cero el objeto.
Citas estándar relevantes (énfasis mío) a continuación.
Desde [dcl.init#6] :
Para inicializar con valor un objeto de tipo T significa:
si T es un tipo de clase (posiblemente cv calificado) sin un constructor predeterminado ([class.ctor]) o un constructor predeterminado que es proporcionado o eliminado por el usuario, entonces el objeto está inicializado por defecto;
si T es un tipo de clase (posiblemente cv calificado) sin un constructor predeterminado provisto o eliminado por el usuario, entonces el objeto tiene cero inicialización y las restricciones semánticas para la inicialización predeterminada se verifican, y si T tiene un constructor predeterminado no trivial , el objeto está inicializado por defecto;
...
Desde [dcl.init.list] :
La inicialización de lista de un objeto o referencia de tipo T se define de la siguiente manera:
...
De lo contrario, si la lista de inicializadores no tiene elementos y T es un tipo de clase con un constructor predeterminado, el objeto se inicializa con valores.