una ser puede instrucción incrustada etiqueta ejemplos declaración con c if-statement compiler-warnings keil

ser - bytecode java ejemplos



¿Por qué el compilador no me advirtió acerca de una instrucción if vacía? (2)

Estoy usando Keil uVision v4.74 y he habilitado la opción "Todas las advertencias".

Escribí el siguiente código intencional :

if(condition matched) { //do something }

Cuando reconstruí mi proyecto, obtuve 0 errores, 0 advertencias.

Sin embargo, cuando accidentalmente escribí:

if(condition matched); { //do something }

También tengo 0 errores, 0 advertencias.

Era casi imposible para mí descubrir que era pequeño ; seguir la condición if era la raíz del problema.

¿Por qué el compilador no lo trató como una advertencia y me informó?


Como lo indicó la respuesta de Matteo, el código es absolutamente válido. Está siendo interpretado de esta manera:

if(condition) ; // do nothing // unrelated block { // do something }

Es un poco técnico, pero las condiciones con cuerpos vacíos tienen algunos usos muy buenos.

Lint y otras herramientas de cordura de código de este tipo advertirán sobre el cambio inesperado en la sangría, y detectarán errores adicionales que pueden ser estilísticos aunque técnicamente no sean errores del compilador.

O problemas de seguridad, contaminación variable, gestión de búfer, posibles problemas de mantenimiento, como malos lanzamientos, etc. Hay una gran cantidad de problemas de código que no entran en la categoría de "errores de compilación".

Como se mencionó en @ jpmc26, este enfoque puede ser mejor ya que no es necesario cambiar los compiladores para usarlo. Aunque personalmente también encuentro valor en la capacidad de ejecutar los dos de forma independiente.


No es un error porque una declaración vacía es una declaración válida; sin embargo, dado que ciertamente es un código sospechoso, es el candidato perfecto para una advertencia de compilación, y de hecho, gcc -Wall -Wextra advierte al respecto:

int foo(int x) { if(x); { return 42; } return 64; }

/tmp/gcc-explorer-compiler116427-37-l1vpg4/example.cpp: In function ''int foo(int)'': 2 : warning: suggest braces around empty body in an ''if'' statement [-Wempty-body] if(x); { ^

https://godbolt.org/g/RG1o7t

tanto clang como VC ++ también lo hacen.

gcc 6 es aún más inteligente (bueno, tal vez demasiado), y toma incluso la sangría como una pista de que algo anda mal:

/tmp/gcc-explorer-compiler116427-76-1sfy0y/example.cpp: In function ''int foo(int)'': 2 : warning: suggest braces around empty body in an ''if'' statement [-Wempty-body] if(x); { ^ 2 : warning: this ''if'' clause does not guard... [-Wmisleading-indentation] if(x); { ^~ 2 : note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ''if'' if(x); { ^

Entonces, o no tiene las advertencias lo suficientemente altas, o su compilador no es lo suficientemente inteligente.

Si no tiene la posibilidad de cambiar a un compilador más útil, considere usar herramientas de análisis estático; por ejemplo, en este caso, cppcheck detecta el error (cuando se le da --enable=all --inconclusive flags):

[mitalia@mitalia ~/scratch]$ cppcheck --enable=all --inconclusive emptyif.c Checking emptyif.c... [emptyif.c:2]: (warning, inconclusive) Suspicious use of ; at the end of ''if'' statement. [emptyif.c:1]: (style) The function ''foo'' is never used.

Adición: advertencias relevantes para varios compiladores (no dude en actualizar)

para recapitular, las opciones de advertencia relevantes son:

  • gcc -Wempty-body ; incluido en -Wextra ;
  • gcc > = 6.0, también -Wmisleading-indentation puede ayudar; incluido en -Wall ;
  • clang -Wempty-body ; incluido en -Wextra también;
  • Visual C ++ C4390 , incluido en /W3

Herramientas de análisis estático:

  • cppcheck - habilitado --enable=warning --inconclusive ; incluido en --enable=all --inconclusive