Encontrar "fallthroughs" en el código C
switch-statement static-analysis (2)
Se descubrieron varios errores desagradables en un producto en el que estoy trabajando, todos relacionados con "errores" inadvertidos en las declaraciones de cambio.
Ahora, me gustaría ir un paso más allá. Me gustaría detectar cómo se desvanece la declaración de cambio en un gran cuerpo de código C. Solo puedo usar Linux y gcc 5.6 para la compilación (por lo tanto, no hay clang o un gcc más nuevo; esto se debe a que gcc más nuevo no existe para la arquitectura de destino de nuestro proyecto).
Este es un código sin caerse:
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something
break;
case 2:
case 3:
case 4:
// Do something
break;
}
Este es un código con errores:
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something but fall through to the other cases
// after doing it.
case 2:
case 3:
case 4:
// Do something else.
break;
}
Si está utilizando GCC, debe usar la opción del compilador Wimplicit-fallthrough
para generar una advertencia para fallthroughs. Alternativamente, puede convertirlo en un error utilizando -Werror
(es decir, -Werror=implicit-fallthrough
para esta advertencia específica.
Preferiría usar -Wextra
(que incluye este y muchos otros avisos adicionales), pero si se trata de una gran base de código heredada, podría generar demasiado ruido. Es lo que debes esforzarte, pasar la compilación con -Wextra -Wpedantic -Werror
.
Si la versión del compilador no es compatible con dicha opción, tal vez pueda escribir su propia expresión regular que coincida con todas las case
y case
sin un prefijo de case
anterior, aunque deberá tener cuidado para asegurarse de que la expresión regular coincida con todas las ocurrencias, independientemente de formateo / comentarios.
Por ejemplo, podría usar algo como esto (aquí hay una demostración ):
(?# match any ''case'' following ''break;'', '':'' or ''{'' into a non-capturing group)
(?# then match the remaining ''case'' into a named "fallthrough" group)
(?:(break;|:|{)[/r/n/s]*case) | (?<fallthrough>case)
De modo que puede ejecutar un script perl (o python, o lo que sea) contra su carpeta y volcar todas las líneas donde se captura el grupo "fallthrough".
Sugeriría compilar su código con un compilador más nuevo solo para detectarlos (sé que mencionó que no podría hacer eso para el proyecto, pero a veces es útil compilarlo con otra cosa para tener una perspectiva diferente de las cosas).
Lo que tenemos en mi trabajo es una versión (lamentablemente) vieja de GCC compilando nuestro código "oficial" y clang haciendo una compilación falsa solo para tener un mejor análisis estático.