Ejecute una verificación específica de clang-tidy en toda su base de código

 C Programming >> Programación C >  >> Tags >> Clang
Ejecute una verificación específica de clang-tidy en toda su base de código

Recientemente realicé una refactorización importante en una pieza de código que involucraba miles de líneas de código que estaban relacionadas de una forma u otra con el manejo de cadenas. Todo el código manejaba char* (matrices de punteros de caracteres de estilo C) y el concepto de const o la propiedad era literalmente desconocida en esa parte de la base de código. El código refactorizado usa std::string 's, pero debido a la naturaleza heredada, una gran cantidad de métodos devolvieron nullptr 's en lugar de cadenas vacías (como "" ). Entiendo por qué se hizo esto, pero encontrar todas esas instancias y el hecho de que solo da un error de tiempo de ejecución fue un poco fastidioso.

Por suerte clang-tidy está aquí para salvar el día. En mi IDE, CLion, da una advertencia cuando devuelve un nullptr . Sin embargo, solo hace eso en el archivo que está editando actualmente, y dado que estamos hablando de millones de archivos, no iba a abrirlos a mano. Puedes ejecutar clang-tidy fácilmente en un archivo, y no es difícil ejecutarlo también en un código base completo, usando el scriptrun-clang-tidy.py , provistos en sus paquetes.

Este fragmento le muestra cómo ejecutar un clang-tidy específico comprobar, en mi caso, bugprone-string-constructor , en una base de código (cmake y C++).

Aquí está el mensaje ordenado de clang en CLion:

Código de ejemplo con comportamiento indefinido

Este es un ejemplo de código que demuestra el comportamiento:

#include <string>
#include <iostream>

class Example {
public:
    std::string getName() { return nullptr; }
};

int main() {
    Example ex;
    std::cout << "Example: " << ex.getName() << std::endl;
    return 0;
}

Si intenta ejecutar el ejemplo de código anterior, obtendrá un error de tiempo de ejecución:

terminate called after throwing an instance of 'std::logic_error'
    what():  basic_string::_M_construct null not valid

Opiniones sobre nullptr y std::string difieren dependiendo de a quién le preguntes, pero a partir de ahora no es posible construir un std::string con un nullptr .

Ejecute clang-tidy en todo su código base

Asegúrate de tener clang-tidy instalado:

apt install clang-tidy

Navega a la carpeta de tu proyecto:

cd my/cpp/project

Si aún no lo ha hecho, cree una carpeta de compilación (mkdir build; cd build ) y ejecute cmake con una bandera adicional para crear la base de datos de compilación para clang-tidy :

cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug 

En la carpeta de compilación, ejecute run-clang-tidy . Podría ser un comando diferente (run-clang-tidy.py o run-clang-tidy-VERSIONNUMBER ) según la preferencia de empaquetado de su distribución.

run-clang-tidy -extra-arg=-Wno-unknown-warning-option -checks='-*,bugprone-string-constructor' 2>&1 | tee -a clang-tidy-result

Esto tomará un tiempo, cuando termine el comando, puede mirar los resultados, o en el archivo clang-tidy-result . En mi caso, dio nombres de archivos específicos y números de línea donde encontró el comportamiento indefinido.

El -extra-arg fue requerido debido a algún otro indicador de extensión del compilador para nuestro código, probablemente pueda omitirlo.

El -checks='-*' deshabilita todas las comprobaciones, el siguiente ,bugprone-string-constructor habilita solo la verificación de cadena específica que quiero ejecutar. Puede agregar controles más específicos, sepárelos con una coma. Un ejemplo con solo 2 comprobaciones habilitadas:

-checks='-*,bugprone-string-constructor,bugprone-string-integer-assignment'

Una lista actualizada de clang-tidy los cheques se pueden encontrar en el sitio web de LLVM.


No