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

Vi una publicación sobre que PVS finalmente aprendió a analizar en Linux, así que decidí probarlo en mis proyectos. Y esto es lo que resultó.


Contenido

  1. Ventajas
  2. Desventajas
  3. Resultados
  4. Póscrito

Ventajas

Soporte receptivo

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

Documentación bastante clara

Pude iniciar el analizador sin muchos problemas. También hay ayuda para los comandos de consola (aunque aquí hay quejas, ver sección Desventajas).

Posibilidad de análisis multiproceso

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

Buena visualización

Muchos formatos de salida diferentes, desde texto hasta una pequeña interfaz web. La interfaz web es cómoda, concisa, con sugerencias junto a las líneas en el código y enlaces a descripciones de diagnósticos..

Integración sencilla en la construcción

Toda la documentación está en su sitio web, solo diré que si su proyecto se compila con CMake, es muy fácil.

Buenas descripciones de diagnósticos

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

Desventajas

Desconocimiento del analizador sobre el lenguaje C++

Desafortunadamente, PVS a veces se equivoca en la sintaxis y genera mensajes falsos positivos con código 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í, la palabra clave auto puede significar void, para eso está auto. Pero PVS generó mensajes así:

dynamic_tuple_management.hpp:29:1: error: V591 La función no nula debería devolver un valor.
dynamic_tuple_management.hpp:29:1: error: V2542 La función con un tipo de retorno no nulo debería devolver un valor desde todas las rutas de salida.

Sitio web muy lento

Sí, en la interfaz web junto a cada mensaje hay un enlace a la descripción del diagnóstico correspondiente con ejemplos. Pero al hacer clic en el enlace, se tiene que esperar bastante tiempo, y a veces aparece incluso 504 Gateway Time-out.

Lenguaje

Todas las descripciones están en ruso, lo cual es excelente. Pero los enlaces del informe siempre conducen a la versión en inglés. Sería bueno tener la opción de cambiar el idioma, para que las descripciones se puedan ver directamente en ruso. En la interfaz no encontré tal opción.

Es incómodo trabajar con los niveles de diagnóstico a través de la consola

Empecemos por el hecho de que los dos comandos utilizados (esto es pvs-studio-analyzer y plog-converter) tienen diferentes formatos para especificar diagnósticos.

La ayuda de pvs-studio-analyzer indica:

-a [MODE], --analysis-mode [MODE]
    MODE define el tipo de advertencias:
    1 - errores de 64 bits;
    2 - reservado;
    4 - Análisis General;
    8 - Micro-optimizaciones;
    16 - Solicitudes específicas de los clientes;
    32 - MISRA.
    Los modos se pueden combinar sumando los valores
    Predeterminado: 4

Llevé mucho tiempo tratando de entender dónde debía agregar ("adding the values") las claves. Intenté enumerarlas separadas por comas:

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

Intenté escribir la clave varias veces:

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

Y solo después me di cuenta de que ¡son máscaras de bits! Y es necesario sumar, y no agregar los valores. Por ejemplo, para obtener diagnósticos generales, diagnósticos de micro-optimizaciones y MISRA, hay que sumarlos (4 + 8 + 32 = 44):

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

El uso de máscaras de bits en interfaces de usuario es, por lo general, de mal gusto. Todo esto se podría haber sumado internamente, y al usuario se le podría haber presentado un conjunto de flags.

Además, hay otra utilidad plog-converter, que genera información legible sobre el análisis estático. Tiene sus propios inconvenientes.

La ayuda del programa plog-converter informa:

-a, --analyzer            Especifica el(los) analizador(es) y el(los) nivel(es) a utilizar para el filtrado, es decir,
                          'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
                          Predeterminado: GA:1,2

Aquí han aparecido unos "niveles" que antes no estaban en ninguna parte, y tampoco encontré nada sobre ellos en la documentación.

En general, no está claro. Por eso, todo lo configuré al máximo.

Un montón de advertencias inútiles en Catch

En dos de los tres proyectos que analicé, se utiliza la biblioteca de pruebas unitarias Catch2. Y la mayoría de los mensajes (!!! 90 de 138 en uno y 297 de 344 en otro !!!) son del siguiente tipo:

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

No considera la multithreading

Muchos falsos positivos sobre supuestas variables inmutables o bucles infinitos, mientras que el trabajo con estas variables ocurre desde diferentes hilos, y si no fuera así, las pruebas unitarias no habrían funcionado.

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

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

Resultados

PVS no encontró ningún error real en mis proyectos abiertos Burst y Proxima, así como en un proyecto laboral que, por razones obvias, no puedo presentar. Sin embargo, es importante tener en cuenta que algunas deficiencias ya habían sido detectadas y corregidas previamente con Cppcheck y scan-build.

En general, la impresión de todos estos analizadores es bastante similar: sí, captan algo, a veces incluso algo importante, pero en general un compilador es suficiente.

Quizás (y me gusta pensar así), nuestro equipo utiliza prácticas de desarrollo de software que permiten generar la mínima cantidad de código basura. Es mejor no crear problemas que superarlos heroicamente.

Por eso, me atrevo a dar algunos consejos sobre cómo programar en C++ para no dispararse en el pie ni golpear con un rastrillo en la frente.

Utiliza las diagnósticas del compilador al máximo

Nuestro equipo utiliza (y te recomienda) 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

Inclúyelas en tu proyecto, aprenderás mucho sobre tu código.

Sigue el estándar

Intenta no usar cosas específicas de la plataforma, si hay análogos estándar, y si realmente no puedes prescindir de ellas, envuélvelas en bloques especiales bajo macros (o de alguna otra manera) y simplemente no dejes que tu código se compile en condiciones no soportadas.

Sigue la semántica estándar de las operaciones

La suma debe ser suma, la multiplicación — multiplicación, la llamada a función — llamada a función, la copia debe copiar, el movimiento — mover, el contenedor debe ser iterable, el iterador debe tener avance ++ y desreferenciación *. Y así sucesivamente, y así sucesivamente.

Creo que la idea está clara. Hay convenciones establecidas que no son obligatorias, pero que todos los usuarios y lectores de tu código esperan ver. No intentes ser más astuto que los demás, o terminarás engañándote a ti mismo.

Escribe código compatible

En primer lugar, me refiero a la biblioteca estándar. Es muy deseable que las interfaces de tus clases y funciones puedan ser utilizadas con bibliotecas estándar y otras (por ejemplo, Boost).

No dudes en echar un vistazo a las interfaces de STL y Boost. Con raras excepciones, allí verás un digno ejemplo a seguir.

Utiliza al máximo las herramientas abiertas

Para el mismo análisis estático, existen al menos dos herramientas gratuitas de código abierto que se conectan a cualquier proyecto con el sistema de construcción CMake.

Puedes leer más al respecto en mi publicación reciente..

Póscrito

Por último, quiero subrayar que no estoy sugiriendo dejar de usar PVS u otros analizadores estáticos. Pero insto a reflexionar sobre cómo es posible que un analizador estático encuentre constantemente errores significativos en tu código.

Esto es solo una consecuencia. Hay que buscar y eliminar la causa.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster