c++ - ¿Cómo puedo hacer que gcc me advierta sobre "int i=i;"
std compiler-warnings (3)
Un programa simple:
int main()
{
long i = i;
return 0;
}
Compilar como C no da errores ni advertencias.
$ gcc -Wall -Wextra -pedantic 1.c
Compilar como C ++ da una advertencia:
$ c++ -Wall -Wextra -pedantic 1.c
1.c: In function ‘int main()’:
1.c:3:7: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
long i = i;
En ambos casos, la variable i parece ser 0, aunque en c ++ podría estar sin inicializar. De hecho, hice un error tipográfico en una de mis funciones y fue bastante difícil encontrarlo. ¿Qué puedo hacer para evitar esto? Yo esperaría al menos una advertencia. Además, Clang no da ninguna advertencia en ninguno de los casos (c o c ++). ¿Hay una parte específica de la norma que diga algo sobre este comportamiento?
Editar: Habiendo probado algo similar:
$ cat 1.c
int main(void)
{
int k = k + 0;
int i = i + 1;
return 0;
}
La advertencia (en C) se genera solo para "i".
$ gcc -Wall -Wextra 1.c
1.c: In function ‘main’:
1.c:4:6: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
int i = i + 1;
Es básicamente:
int i;
i = i;
en el que i
es un valor no inicializado.
La combinación de -Wall -Winit-self
parece agregar este diagnóstico:
$ gcc -Wall -Winit-self t.c
t.c: In function ‘main’:
t.c:3:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
long i = i;
^
Para GCC que compila programas en C, debe agregar el indicador del compilador -Winit-self
. (También necesita -Wall
o -Wuninitialized
, consulte a continuación). Para GCC que compila programas en C ++, esta -Wall
está implícita en -Wall
pero para C debe especificarse explícitamente; Tampoco es parte de -Wextra
.
Para Clang, la situación es un poco más interesante. En el fragmento en el OP, Clang no produce ningún diagnóstico. Sin embargo, con el fragmento ligeramente diferente suministrado en el manual de GCC a continuación, se proporciona un diagnóstico:
int f() {
int i = i;
return i;
}
La diferencia es que en el fragmento anterior, el valor (sin inicializar) de i
se usa realmente. Aparentemente, en el código original, Clang detectó que la variable era inútil y la eliminó como código muerto antes de aplicar el diagnóstico.
En Clang, el diagnóstico se activa con -Wuninitialized
, que se habilita con -Wall
como en GCC.
Aquí hay un extracto del manual de GCC:
-Winit-self
(solo C, C ++, Objective-C y Objective-C ++)Avisar sobre las variables no inicializadas que se inicializan con ellas mismas. Tenga en cuenta que esta opción solo se puede utilizar con la opción
-Wuninitialized
.Por ejemplo, GCC advierte acerca de que no esté inicializado en el siguiente fragmento solo cuando se
-Winit-self
:
int f() { int i = i; return i; }
Esta advertencia está habilitada por
-Wall
en C ++.
Como indica el extracto, -Wuninitialized
también es necesario. En C y C ++, -Wall
implica -Wuninitialized
. Sin embargo, tenga en cuenta que muchos usos no inicializados no se detectarán a menos que también se solicite algún nivel de optimización. (Eso no se aplica a -Winit-self
, que yo sepa. Puede detectarse sin optimización).
Irritante, cuando se desmarca una pregunta como un duplicado, los duplicados marcados previamente desaparecen. Lo desmarqué porque ninguno de los duplicados contestó realmente la pregunta en el cuerpo; También edité el título.
Para referencia, aquí están los duplicados originales, que pueden ser de interés: