c++ - bitwise operators c
Cómo habilitar las advertencias de C++ para operadores bitwise con argumentos booleanos (1)
Mientras trabajaba con una base de código C ++ bastante grande y la cadena de herramientas GCC en Linux, encontré un código que realiza una comprobación booleana de la siguiente manera:
#include <stdio.h>
int main() {
bool foo = true;
if (~foo) {
// do some expensive operation
printf("This can be bad.../n");
}
return 0;
}
Esto parece un error obvio, ya que el operador ~
representa bit-NO en C ++, y no es lógico, como diría, en MATLAB. El código anterior siempre se evaluaría como verdadero
Afortunadamente, el problema causado por este error no fue importante (solo fue un pequeño golpe de rendimiento), pero me hizo pensar en cómo no se había encontrado este error en mucho tiempo.
Dado que el operador bit a bit activa una conversión implícita del booleano a un entero, que es una promoción, no hay nada malo en ello per se . Sin embargo, a mí me parece que al menos algo como clang-tidy
debería ser capaz de tomar esto como un error lógico, ya que es bastante claro que en la mayoría de los casos, la intención no es aplicar una operación de bit a sabia a un bool, pero en cambio una lógica.
g++
no parece preocuparse por este problema, incluso con -Wall -Wextra -Wconversion
habilitado, lo cual es sensato dado que, como mencioné anteriormente, esto no está en contra de la norma. (Incluso probé g++
6.3, que debería tener muchos controles nuevos y aún no tengo nada)
El uso de clang-tidy
con todas las comprobaciones activadas (lo que puede ser realmente ruidoso realmente rápido) advierte sobre la conversión implícita en sí misma ("bool de conversión implícita -> ''int''"), pero no parece haber una advertencia específica relacionada con aplicando operadores bit -wise a los booleanos.
Escribir la instrucción if de manera diferente if(~foo == true)
, aunque detallado y conduciendo a un escenario siempre falso, conduce a errores más significativos que pueden llamar la atención sobre el error, pero esto no sucede cuando el terser if(~foo)
se usa la forma if(~foo)
.
¿Hay alguna forma / herramienta para verificar estos problemas, que son 100% correctos en C ++, pero es muy probable que haya errores?
Hay -Wbool-operation
en gcc a partir de gcc 7:
Avisar sobre operaciones sospechosas en expresiones de tipo booleano. Por ejemplo, la negación a nivel de bits de un booleano es muy probable que sea un error en el programa. Para C, esta advertencia también advierte sobre el incremento o decremento de un booleano, lo que rara vez tiene sentido. (En C ++, la reducción de un valor booleano siempre es inválida. Incrementar un valor lógico es inválido en C ++ 1z, y de lo contrario se desaprueba).
Esta advertencia está habilitada por -Wall.
Proporciona la siguiente advertencia para su programa:
prog.cc:6:9: warning: ''~'' on an expression of type bool [-Wbool-operation]
if (~foo) {
^~~
prog.cc:6:9: note: did you mean to use logical not (''!'')?
demo gcc
Desafortunadamente, no parece que clang 5 tenga tal opción. Incluso activando (casi) todas las advertencias posibles que se enumeran here , todavía no recibimos la advertencia esperada ( Demo ) (aunque sí algunas otras interesantes).
Finalmente, para completar, MSVC 19.00.23506 definitivamente advierte ( Demo ) (crédito a @cbuchart por señalar esto):
source_file.cpp(8): warning C4804: ''~'': unsafe use of type ''bool'' in operation