Revisión independiente de PVS-Studio (Linux, C++)

Vi una publicación que PVS había aprendido a analizar en Linux y decidí probarla en mis propios proyectos. Y esto es lo que surgió de ello.


contenido

  1. Pros
  2. Contras
  3. resultados
  4. Epílogo

Pros

Soporte receptivo

Solicité una clave de prueba y me la enviaron el mismo día.

Documentación bastante clara

Logramos iniciar el analizador sin ningún problema. También está disponible ayuda para los comandos de la consola (aunque hay algunas quejas aquí, consulte la sección Contras).

Posibilidad de análisis multiproceso.

El analizador tiene una opción "estándar" -j, permitiendo realizar análisis en paralelo en varias tareas. Esto ahorra mucho tiempo.

Buena visualización

Muchos formatos de salida diferentes, desde texto hasta un pequeño bozal web. La interfaz web es cómoda y concisa, con sugerencias junto a las líneas del código y enlaces a descripciones de diagnóstico..

Fácil integración en el conjunto

Toda la documentación está en su sitio web, solo puedo decir que si su proyecto está construido usando CMake, entonces todo es muy simple.

Buenas descripciones diagnósticas.

Si genera salida en modo fullhtml, luego cada mensaje tiene un enlace a una descripción de diagnóstico, con explicaciones, ejemplos de código y enlaces adicionales.

Contras

Ignorancia del lenguaje C++ por parte del analizador.

Desafortunadamente, PVS a veces comete errores de sintaxis y genera mensajes falsos positivos cuando el código es completamente correcto.

Por ejemplo, hay una función que devuelve void:

template <typename T>
auto copy (const void * source, void * destination)
    ->
        std::enable_if_t
        <
            std::is_copy_constructible<T>::value
        >
{
    new (destination) T(*static_cast<const T *>(source));
}

Sí, palabra clave auto Puede significar void, para eso es auto. Pero PVS produjo los siguientes mensajes:

dynamic_tuple_management.hpp:29:1: error: V591 Non-void function should return a value.
dynamic_tuple_management.hpp:29:1: error: V2542 Function with a non-void return type should return a value from all exit paths.

Sitio muy lento

Sí, en la interfaz web al lado de cada mensaje hay un enlace a la descripción del diagnóstico correspondiente con ejemplos. Pero cuando haces clic en un enlace, tienes que esperar bastante tiempo y, a veces, sucede. 504 Pasarela fuera.

idioma

Todas las descripciones están en ruso, lo cual es genial. Pero los enlaces del informe siempre conducen a la versión en inglés. Sería bueno poder cambiar el idioma para poder ver los diagnósticos inmediatamente en ruso. No encontré esa opción en la interfaz.

Es inconveniente trabajar con niveles de diagnóstico a través de la consola.

Comencemos con el hecho de que los dos comandos utilizados (este pvs-studio-analyzer и plog-converter) diferentes formatos para especificar diagnósticos.

Ayuda para pvs-studio-analyzer lee:

-a [MODE], --analysis-mode [MODE]
    MODE defines the type of warnings:
    1 - 64-bit errors;
    2 - reserved;
    4 - General Analysis;
    8 - Micro-optimizations;
    16 - Customers Specific Requests;
    32 - MISRA.
    Modes can be combined by adding the values
    Default: 4

Pasé mucho tiempo tratando de descubrir adónde ir añadir (“sumar los valores”). Intenté enumerarlos separados por comas:

pvs-studio-analyzer analyze ... -a 1,4,16

Intenté registrar la clave varias veces:

pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16

¡Y sólo entonces me di cuenta de que eran pequeñas máscaras! y necesitas resumirY no añadir significados. Por ejemplo, para obtener diagnósticos generales, diagnósticos de microoptimizaciones y MISRA, es necesario resumirlos (4 + 8 + 32 = 44):

pvs-studio-analyzer analyze ... -a 44

El uso de máscaras de bits en las interfaces de usuario es generalmente de mala educación. Todo esto podría resumirse internamente y se podría establecer un conjunto de indicadores para el usuario.

Además, también existe una utilidad. plog-converter, que genera información de análisis estático legible por humanos. Tiene otros problemas.

Ayuda para el programa plog-converter informes:

-a, --analyzer            Specifies analyzer(s) and level(s) to be
                          used for filtering, i.e.
                          'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
                          Default: GA:1,2

Aquí aparecieron algunos "niveles" que no estaban allí antes, y tampoco encontré nada sobre ellos en la documentación.

En general no está claro. Por eso puse todo al máximo.

Un montón de estúpidas palabrotas sobre Catch

Dos de los tres proyectos que analicé utilizan una biblioteca de pruebas unitarias. Catch2. Y la mayor parte de los mensajes (¡¡¡90 de 138 en uno y 297 de 344 en el otro!!!) tienen el siguiente formato:

Revisión independiente de PVS-Studio (Linux, C++)

No tiene en cuenta el multihilo

Hay muchos falsos positivos sobre variables supuestamente inmutables o bucles sin fin, mientras que el trabajo con estas variables se realiza desde diferentes subprocesos, y si no fuera así, las pruebas unitarias no funcionarían.

Revisión independiente de PVS-Studio (Linux, C++)

Sin embargo, ¿puede un analizador estático tener esto en cuenta? No lo sé.

resultados

PVS no encontró ningún error real en mis proyectos de código abierto Ráfaga и Proxima, así como en un borrador de trabajo que, por razones obvias, no puedo presentar. Es cierto que vale la pena tener en cuenta que algunas deficiencias ya se han detectado y corregido anteriormente utilizando Comprobación de CPP и scan-build.

En general, la impresión de todos estos analizadores es aproximadamente la misma: sí, detectan algo, a veces incluso algo importante, pero en general el compilador es suficiente.

Es posible (y personalmente me gusta pensar que sí) que nuestro equipo utilice prácticas de desarrollo de software que nos permitan generar una cantidad mínima de código de mierda. Es mejor no crear problemas que superarlos heroicamente.

Por lo tanto, me tomo la libertad de dar algunos consejos sobre cómo escribir en C++ de tal manera que no le disparen las piernas a nadie ni le golpeen la frente con un rastrillo.

Aproveche al máximo los diagnósticos del compilador

Nuestro equipo utiliza (y le aconseja) las siguientes opciones de compilación:

-Werror

-Wall
-Wextra
-Wpedantic

-Wcast-align
-Wcast-qual
-Wconversion
-Wctor-dtor-privacy
-Wenum-compare
-Wfloat-equal
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wredundant-decls
-Wsign-conversion
-Wsign-promo

Habilítelos en su proyecto y aprenda mucho sobre su código.

Cíñete al estándar

Trate de no utilizar elementos que dependan de la plataforma si existen análogos estándar, y si no puede prescindir de ellos en absoluto, envuélvalos en bloques especiales para macros (u otra cosa) y simplemente no permita que su código se compile en condiciones no compatibles.

Cíñete a la semántica de operación estándar

La suma debe ser suma, la multiplicación debe ser multiplicación, la llamada a función debe ser llamada a función, la copia debe ser copia, el acarreo debe ser acarreo, el contenedor debe ser iterable, el iterador debe tener promoción ++ y desreferenciación *. Y así sucesivamente y así sucesivamente.

Creo que la idea es clara. Existen convenciones establecidas que no son vinculantes, pero que todos los usuarios y lectores de su código esperan ver. No intentes burlar a los demás, de lo contrario te burlarás de ti mismo.

Escribir código compatible

En primer lugar, me refiero a la biblioteca estándar. Es muy deseable que las interfaces de sus clases y funciones se puedan utilizar con bibliotecas estándar y de otro tipo (por ejemplo, Boost).

No dudes en echar un vistazo a las interfaces STL y Boost. Salvo raras excepciones, allí encontrará un digno modelo a seguir.

Aprovecha al máximo las herramientas de código abierto

Para el mismo análisis estático, existen al menos dos herramientas abiertas y gratuitas que se pueden conectar una sola vez a cualquier proyecto con el sistema de compilación CMake.

Puedes leer más sobre esto en mi reciente publicación..

Epílogo

Finalmente, me gustaría enfatizar que no estoy recomendando no utilizar PVS ni ningún otro analizador estático. Pero le invito a pensar en cómo sucedió que el analizador estático encuentra constantemente errores importantes en su código.

Esto es sólo una consecuencia. Necesitamos buscar y eliminar la causa.

Fuente: habr.com

Añadir un comentario