Pregunta Advertencia GCC [Wuninitialized]


¿Por qué GCC 4.7 se queja cuando crea una instancia dentro de una función (con un puntero)?

Malo:

#include "foo.h"

int fn () {
    Foo *foo;
    foo->method();

   return 0;
}

main.cpp: en la función miembro 'int foo ()':   main.cpp: 21: 52: advertencia: 'fn' puede usarse sin inicializar en este   función [-uninicializado]

Bueno:

#include "foo.h"

Foo *foo;

int fn () {
    foo->method();

   return 0;
}

Bueno:

#include "foo.h"

int fn () {
    Foo foo;
    foo.method();

   return 0;
}

5
2018-01-08 21:10


origen


Respuestas:


Hay una diferencia entre Foo * foo; y Foo foo; El primero declara una puntero a un Foo, el segundo declara e invoca el constructor predeterminado de un Foo.

EDIT: tal vez querías escribir Foo * foo= new Foo();, para asignar un Foo en el montón que puede sobrevivir la llamada de función.


6
2018-01-08 21:12



El primero (malo), foo está apuntando a un puntero de basura. Podrías eliminar la advertencia inicializándola como Foo* foo = NULL; pero luego obtendría un error cuando intentó desreferenciarlo (error de tiempo de ejecución).

El segundo (bueno) no se queja porque C inicializa automáticamente las variables en el alcance de la unidad de traducción a NULL o 0 o el equivalente apropiado si aún no están inicializadas.

El último (bueno) no se queja porque está llamando a un método en el objeto y la asignación del puntero a la función la realiza el compilador, similar pero no igual al número 2. Por lo tanto, el compilador ya conoce la dirección del método method y ha asignado esa dirección a la ubicación apropiada en el Foo estructura


5
2018-01-08 21:15



Foo* foo; foo->method() es Nunca bueno. foo es un puntero no inicializado que potencialmente apunta a basura y, como tal, su código muestra un comportamiento indefinido. los mejor lo que puede esperar es que el compilador le avise o cometa errores. Si no es así, entonces al menos espero que el programa en ejecución choques.


2
2018-01-08 21:13



En tu mal ejemplo foo es una variable local con tipo de puntero, que no se inicializa automáticamente. los class Foo, en tu ejemplo correcto, es inicializado usando el constructor predeterminado.

Su primer ejemplo "bueno" inicializa el puntero con 0, porque foo es una variable global. Dará lugar a comportamiento indefinido en tiempo de ejecución, desde foo no apunta a un objeto.


2
2018-01-08 21:14



Porque, justo como dice la advertencia, no está inicializado. no hay ningún objeto todavía en realidad, el valor de foo en tu primer ejemplo no está definido. Tendrá el valor que reside en la memoria donde vive foo.

para aclarar, foo (que ves como Foo *) es en realidad un int. se supone que el valor de int es la dirección de un objeto de tipo Foo. Para hacerlo así, debes asignarle la dirección de un foo. Uno de hacer esto es crear una instancia con nuevo:

Foo* foo = new Foo;

new devuelve la dirección donde se creó el nuevo objeto Foo. esto eliminará tu advertencia :)


2
2018-01-08 21:15