Forma fácil de encontrar variables de miembros no inicializadas

Estoy buscando una manera fácil de encontrar variables de miembro de clase no inicializadas.

Encontrarlos en tiempo de ejecución o tiempo de comstackción está bien.

Actualmente tengo un punto de interrupción en el constructor de la clase y examino las variables miembro una a una.

Si usa GCC, puede usar el -Weffc++ , que genera un aviso cuando una variable no se inicializa en la lista de inicialización de miembros. Esta:

 class Foo { int v; Foo() {} }; 

Lleva a:

 $ g++ -c -Weffc++ foo.cpp -o foo.o foo.cpp: In constructor 'Foo::Foo()': foo.cpp:4: warning: 'Foo::v' should be initialized in the member initialization list 

Un inconveniente es que -Weffc++ también te advertirá cuando una variable tenga un constructor predeterminado adecuado y, por lo tanto, no será necesaria la inicialización. También le avisará cuando inicialice una variable en el constructor, pero no en la lista de inicialización de miembros. Y advierte sobre muchos otros problemas de estilo de C ++, como los constructores de copia faltantes, por lo que es posible que necesite limpiar un poco su código cuando quiera usar -Weffc++ de forma regular.

También hay un error que hace que siempre le avise cuando usa uniones anónimas, que actualmente no puede solucionar y luego apaga la advertencia, lo cual se puede hacer con:

 #pragma GCC diagnostic ignored "-Weffc++" 

En general, sin embargo, he encontrado que -Weffc++ es increíblemente útil para detectar muchos errores comunes de C ++.

Valgrind puede decirle si está en Linux.

Valgrind ( FREE , en Linux) y Purify (en Windows) encuentran variables no inicializadas, punteros no válidos y cosas así al ejecutar su código en una máquina virtual especial.

Esto es fácil de usar y extremadamente poderoso; es probable que encuentre muchos errores más allá de las variables obvias no inicializadas.

Coverity , Klocwork y Lint pueden encontrar variables no inicializadas usando análisis de código estático.

cppcheck encontrará esto, por ejemplo:

 cppcheck my_src_dir --output-file=check.txt --inconclusive --enable=warning 

-Wuninitialized ¿Sin -Wuninitialized ?

(Esto solo verifica si una variable se utiliza sin inicializar, es decir, si

 struct Q { int x, y; Q() : x(2) {} int get_xy() const { return x*y; } }; 

g ++ advertirá solo cuando el usuario llame a get_xy() sin asignar a y )

Visual Studio (MSVC) tiene una opción de comstackdor / sdl (Habilitar comprobaciones de seguridad adicionales) ( http://msdn.microsoft.com/en-us/library/jj161081.aspx ). En tiempo de ejecución, esto:

Realiza la inicialización del miembro de la clase. Inicializa automáticamente los miembros de clase del tipo de puntero a cero en la instanciación de objetos (antes de que se ejecute el constructor). Esto ayuda a evitar el uso de datos no inicializados asociados con los miembros de la clase que el constructor no inicializa explícitamente.

Esto no le ayudará a detectar las variables de miembro no inicializadas en tiempo de comstackción, pero hace que el comportamiento sea más predecible cuando ocurre en tiempo de ejecución. Sin embargo, no debería escribir código que dependa de que esta opción esté habilitada, por supuesto.

Si está utilizando Visual Studio, puede comstackr en modo de depuración, detener el progtwig en el depurador y buscar qué variables se inicializan en bytes que contienen 0xCC (stack) o 0xCD (stack).

Aunque personalmente, invertiría en una herramienta de análisis estático para un enfoque más completo.

/ analizar en Visual Studio (“Team System”)

¡Tener cuidado! Las opciones de comstackción propuestas aquí no son confiables, ni independientes de la versión. Considera el ejemplo simple:

 class A { int a; public: void mA() { printf("haha"); ++a; int g = 2/a; printf("%i\n",g); } }; int main() { A a; a.mA(); } 

Comstackdo con g++ -O3 -Weffc++ -Wuninitialized esto informa informes uninitialized en versiones de gcc hasta 4.6 inclusive, y passess felizmente en 4.7 y 4.8 (probado en MacPorts). Entonces, curiosamente, si eliminamos el printf("haha"); , tanto 4.7 como 4.8 repentinamente ven uninitialized A::a . Clang es un poco mejor, ya que de alguna manera asigna basura (en lugar de 0 conveniente) a vars no inicializados, para que pueda ver su efecto desastroso más fácil / más rápido.

Tampoco tuve mucha suerte al detectar el A::a no inicializado con valgrind ; tal vez el gentlement sugiriendo que valgrind podría proporcionar las opciones apropiadas para detectar este error.

En resumen: gran pregunta, no hay muchas soluciones confiables en este momento … (como yo lo veo).

Clang con clang-analyze puede hacer esto. Eventualmente creará un buen informe HTML que indica cuándo se accede a la variable no utilizada.

Considera el siguiente código

unint.cpp:

 int main() { int a; int b; a++; b = b + 5; return 0; } 

Si el código se comstack con el siguiente comentario, se mostrarán los mensajes de advertencia.

g ++ -O3 – Unint.cpp no ​​inicializado

Nota: el -Winicializado necesita la opción -O3 también.