Zobaczyłem post o tym, że PVS nauczył się analizować w systemach Linux, i postanowiłem spróbować na swoich projektach. I oto, co z tego wynikło.
Spis treści
Responsywne wsparcie
Poprosiłem o klucz próbny, a tego samego dnia go otrzymałem.
Wystarczająco zrozumiała dokumentacja
Uruchomienie analizatora udało się bez większych problemów. Istnieje także pomoc dotycząca poleceń konsolowych (choć są pewne zastrzeżenia, patrz sekcja ).
Możliwość analizy wielowątkowej
Analizator ma opcję "standardową" -j, która pozwala na równoległą analizę w kilku zadaniach. To znacznie oszczędza czas.
Dobra wizualizacja
Wiele różnych formatów wyjściowych, od tekstowego po niewielki interfejs webowy. .
Prosta integracja w budowę
Cała dokumentacja jest na ich stronie, powiem tylko, że jeśli Twój projekt jest budowany za pomocą CMake, to wszystko jest bardzo proste.
Dobre opisy diagnostyki
Jeśli generować wyjście w trybie fullhtml, to przy każdej wiadomości znajduje się link do opisu diagnostyki, z wyjaśnieniami, przykładami kodu i dodatkowymi linkami.
Nieznajomość języka C++ przez analizator
Niestety, PVS czasami myli się w składni i generuje fałszywie pozytywne komunikaty dla całkowicie poprawnego kodu.
Na przykład, jest funkcja, która zwraca 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));
}Tak, słowo kluczowe auto może oznaczać void, tak to już jest auto. Ale PVS zgłosił takie komunikaty:
dynamic_tuple_management.hpp:29:1: błąd: V591 Funkcja typu nie-void powinna zwrócić wartość.
dynamic_tuple_management.hpp:29:1: błąd: V2542 Funkcja o zwracanym typie nie-void powinna zwrócić wartość ze wszystkich ścieżek wyjścia.Bardzo wolna strona
Tak, w interfejsie webowym obok każdej wiadomości jest link do odpowiedniego opisu diagnostyki z przykładami. Ale gdy klikniesz na link, trzeba dosyć długo czekać, a czasami zdarza się nawet .
Język
Wszystkie opisy są w języku rosyjskim, co jest świetne. Ale linki z raportu zawsze prowadzą do wersji angielskiej. Dobrze by było mieć możliwość zmiany języka, aby przeglądać diagnostyki od razu po rosyjsku. W interfejsie nie znalazłem takiej opcji.
Niewygodnie pracować z poziomami diagnostyki przez konsolę
Zacznijmy od tego, że obie używane drużyny (to pvs-studio-analyzer i plog-converter) mają różne formaty zlecenia diagnostyki.
Pomoc do pvs-studio-analyzer głosi:
-a [TRYB], --analysis-mode [TRYB]
TRYB definiuje typ ostrzeżeń:
1 - błędy 64-bitowe;
2 - zarezerwowane;
4 - Analiza ogólna;
8 - Mikrooptymalizacje;
16 - Specyficzne żądania klientów;
32 - MISRA.
Tryby można łączyć przez dodawanie wartości.
Domyślnie: 4Długo próbowałem zrozumieć, gdzie należy dodawać („adding the values”) klucze. Próbowałem wymieniać je przecinkiem:
pvs-studio-analyzer analyze ... -a 1,4,16Próbowałem podawać klucz kilka razy:
pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16I dopiero potem zrozumiałem, że to są maski bitowe! I trzeba suma, a nie dodawać wartości. Na przykład, aby uzyskać ogólne diagnozy, diagnozy mikrooptymalizacji i MISRA, trzeba je zsumować (4 + 8 + 32 = 44):
pvs-studio-analyzer analyze ... -a 44Używanie masek bitowych w interfejsach użytkownika to zazwyczaj zły ton. Można to było wszystko zsumować wewnętrznie, a użytkownikowi ustawić zestaw flag.
Ponadto, istnieje jeszcze narzędzie plog-converter, które generuje czytelną informację o analizie statycznej. Ma ono inne subtelności.
Pomoc do programu plog-converter informuje:
-a, --analyzer Określa analizatory i poziomy, które będą
używane do filtrowania, tzn.
'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
Domyślnie: GA:1,2Pojawiły się tutaj jakieś „poziomy”, których wcześniej nigdzie nie było, a w dokumentacji też nic o nich nie znalazłem.
Ogólnie rzecz biorąc, nie jasne. Dlatego wszystko ustawiłem na maksimum.
Mnóstwo bezsensownego błagania w Catch
W dwóch z trzech projektów, które analizowałem, używana jest biblioteka testowania jednostkowego . I większość wiadomości (!!! 90 z 138 w jednym i 297 z 344 w drugim !!!) ma następujący wygląd:

Nie uwzględnia wielowątkowości
Wiele fałszywych alarmów na temat rzekomych niezmiennych zmiennych lub nieskończonych pętli, podczas gdy praca z danymi tych zmiennych odbywa się z różnych wątków, a gdyby tak nie było, to testy jednostkowe by nie zadziałały.

Zresztą, czy statyczny analizator może w ogóle coś takiego uwzględnić? Nie wiem.
PVS nie znalazł żadnego prawdziwego błędu w moich otwartych projektach i , a także w projekcie roboczym, którego z oczywistych powodów nie mogę przedstawić. Warto jednak pamiętać, że niektóre niedociągnięcia zostały już wcześniej wychwycone i naprawione. i .
Ogólnie wrażenie ze wszystkich tych analizatorów jest w przybliżeniu takie samo: tak, coś łapią, czasami nawet coś ważnego, ale w całości wystarczy kompilator.
Może (i osobiście miło mi tak myśleć), że nasz zespół stosuje takie praktyki w rozwoju oprogramowania, które pozwalają generować minimalną ilość złej jakości kodu. Lepiej nie stwarzać problemów, niż heroicznie je przezwyciężać.
Dlatego pozwalam sobie dać kilka wskazówek dotyczących tego, jak pisać w języku C++, aby nikomu nie strzelać w nogi i nie dostawać w głowę od grabli.
Wykorzystuj diagnostykę kompilatora maksymalnie.
Nasz zespół wykorzystuje (i radzi wam) następujące opcje kompilacji:
-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-promoZintegruj je w swoim projekcie, a dowiesz się wiele nowego o swoim kodzie.
Przestrzegaj standardu.
Staraj się nie używać rzeczy zależnych od platformy, jeśli istnieją standardowe odpowiedniki, a jeśli już całkowicie nie da się bez nich obejść, zapakuj je w specjalne bloki pod makrosy (lub w inny sposób) i po prostu nie pozwól skompilować swojego kodu w nieobsługiwanych warunkach.
Przestrzegaj standardowej semantyki operacji.
Dodawanie powinno być dodawaniem, mnożenie — mnożeniem, wywołanie funkcji — wywołaniem funkcji, kopiowanie powinno kopiować, przeniesienie — przenosić, kontener powinien być iterowalny, iterator powinien mieć pełzanie ++ i dereferencję. *. I tak dalej, i tak dalej.
Myślę, że myśl jest jasna. Istnieją ustalone konwencje, które nie są obowiązkowe, ale które wszyscy użytkownicy i czytelnicy twojego kodu oczekują zobaczyć. Nie próbuj przechytrzyć innych, bo sam się przechytrzysz.
Pisz kompatybilny kod.
Przede wszystkim mam na myśli standardową bibliotekę. Bardzo pożądane, aby interfejsy twoich klas i funkcji mogły być używane z bibliotekami standardowymi i innymi (np. Boost).
Nie krępuj się zaglądać do interfejsów STL i Boost. Z nielicznymi wyjątkami zobaczysz tam godny do naśladowania przykład.
Wykorzystuj maksymalnie otwarte narzędzia.
Istnieje co najmniej dwa otwarte, darmowe narzędzia do analizy statycznej, które można podłączyć do każdego projektu z systemem budowy CMake za pierwszym razem.
.
Na koniec chciałbym podkreślić, że nie namawiam do zaprzestania korzystania z PVS ani innych analizatorów statycznych. Jednak zachęcam do zastanowienia się, jak to się stało, że analizator statyczny regularnie znajduje w twoim kodzie istotne błędy.
To tylko skutek. Należy szukać i eliminować przyczynę.
Źródło: habr.com
