PVS-Studio-ի անկախ վերանայում (Linux, C++)

Ես տեսա մի հրապարակում, որը PVS-ը սովորել էր վերլուծել Linux-ի տակ, և որոշեցի փորձել այն իմ սեփական նախագծերում: Եվ սա այն է, ինչ դուրս եկավ դրանից.


Պարունակություն

  1. Կոալիցիայում
  2. Դեմ
  3. Արդյունքները
  4. Հետո

Կոալիցիայում

Պատասխանատու աջակցություն

Ես փորձնական բանալի խնդրեցի, և նրանք նույն օրը ուղարկեցին ինձ:

Բավական հստակ փաստաթղթեր

Մեզ հաջողվեց առանց խնդիրների գործարկել անալիզատորը։ Հասանելի է նաև վահանակի հրամանների օգնությունը (թեև այստեղ կան որոշ բողոքներ, տես բաժինը Դեմ).

Բազմաթելային վերլուծության հնարավորություն

Անալիզատորն ունի «ստանդարտ» տարբերակ -j, որը թույլ է տալիս վերլուծություն կատարել զուգահեռաբար մի քանի առաջադրանքներում: Սա խնայում է շատ ժամանակ:

Լավ վիզուալիզացիա

Բազմաթիվ տարբեր ելքային ձևաչափեր՝ տեքստից մինչև փոքր վեբ դունչ: Վեբ ինտերֆեյսը հարմար է, հակիրճ, կոդի տողերի կողքին ակնարկներով և ախտորոշիչ նկարագրությունների հղումներով.

Հեշտ ինտեգրում ժողովին

Ամբողջ փաստաթղթերը իրենց կայքում են, կարող եմ միայն ասել, որ եթե ձեր նախագիծը կառուցված է CMake-ի միջոցով, ապա ամեն ինչ շատ պարզ է:

Լավ ախտորոշիչ նկարագրություններ

Եթե ​​դուք արտադրում եք ելք ռեժիմում fullhtml, ապա յուրաքանչյուր հաղորդագրություն ունի հղում դեպի ախտորոշիչ նկարագրություն՝ բացատրություններով, կոդերի օրինակներով և լրացուցիչ հղումներով:

Դեմ

C++ լեզվի անտեղյակություն անալիզատորի կողմից

Ցավոք, PVS-ը երբեմն շարահյուսական սխալներ է թույլ տալիս և կեղծ դրական հաղորդագրություններ է ստեղծում, երբ կոդը լիովին ճիշտ է:

Օրինակ, կա ֆունկցիա, որը վերադարձնում է 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));
}

Այո, հիմնական բառն է auto Կարող է նշանակել void, դրա համար է ավտոմոբիլ. Բայց PVS-ն արտադրեց հետևյալ հաղորդագրությունները.

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.

Շատ դանդաղ կայք

Այո, յուրաքանչյուր հաղորդագրության կողքին գտնվող վեբ ինտերֆեյսում կա հղում դեպի համապատասխան ախտորոշիչ նկարագրությունը՝ օրինակներով: Բայց երբ սեղմում ես հղման վրա, պետք է բավական երկար սպասես, և երբեմն դա տեղի է ունենում 504 Gateway Time-out.

Լեզու

Բոլոր նկարագրությունները ռուսերեն են, ինչը հիանալի է: Սակայն զեկույցի հղումները միշտ տանում են դեպի անգլերեն տարբերակը: Լավ կլինի, եթե կարողանաք փոխել լեզուն, որպեսզի կարողանաք անմիջապես դիտել ախտորոշումը ռուսերենով: ինտերֆեյսում նման տարբերակ չգտա։

Վահանակի միջոցով ախտորոշիչ մակարդակների հետ աշխատելն անհարմար է

Սկսենք նրանից, որ օգտագործված երկու հրամանները (սա pvs-studio-analyzer и plog-converter) ախտորոշման հստակեցման տարբեր ձևաչափեր:

Օգնություն համար pvs-studio-analyzer կարդում է.

-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

Ես երկար ժամանակ ծախսեցի՝ փորձելով պարզել, թե ուր գնալ ավելացնել («ավելացնելով արժեքները») ստեղները: Ես փորձեցի թվարկել դրանք՝ բաժանված ստորակետերով.

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

Ես մի քանի անգամ փորձեցի գրանցել բանալին.

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

Եվ միայն այն ժամանակ ես հասկացա, որ դրանք դիմակներ էին: Եվ դուք պետք է ԱմփոփելԵւ ոչ ավելացնել իմաստներ. Օրինակ, ընդհանուր ախտորոշում, միկրոօպտիմալացման ախտորոշում և MISRA ստանալու համար անհրաժեշտ է դրանք ամփոփել (4 + 8 + 32 = 44).

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

Օգտագործողի ինտերֆեյսներում բիտդիմակների օգտագործումն ընդհանուր առմամբ վատ ձև է: Այս ամենը կարելի է ամփոփել ներսից, և օգտատիրոջ համար սահմանվել դրոշների մի շարք:

Բացի այդ, կա նաև կոմունալ plog-converter, որը ստեղծում է մարդու կողմից ընթեռնելի ստատիկ վերլուծության տեղեկատվություն: Նա այլ խնդիրներ ունի.

Օգնություն ծրագրի համար plog-converter հաղորդում է.

-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

Այստեղ հայտնվեցին որոշ «մակարդակներ», որոնք նախկինում չկային, և ես դրանց մասին ոչինչ չգտա նաև փաստաթղթերում:

Ընդհանուր առմամբ, պարզ չէ. Դրա համար ես ամեն ինչ դրել եմ առավելագույնի վրա։

Մի փունջ հիմար հայհոյանքներ Catch-ի վրա

Իմ վերլուծած երեք նախագծերից երկուսը օգտագործում են միավորի թեստավորման գրադարան Catch2- ը. Իսկ հաղորդագրությունների առյուծի բաժինը (!!! Մեկում 90-ից 138-ը, մյուսում՝ 297-ից 344-ը!!!) ունեն հետևյալ ձևը.

PVS-Studio-ի անկախ վերանայում (Linux, C++)

Հաշվի չի առնում բազմաշերտությունը

Կան բազմաթիվ կեղծ դրական եզրակացություններ իբր անփոփոխ փոփոխականների կամ անվերջ օղակների մասին, մինչդեռ այդ փոփոխականների հետ աշխատանքը տեղի է ունենում տարբեր թելերից, և եթե դա այդպես չլիներ, ապա միավորի թեստերը չէին աշխատի:

PVS-Studio-ի անկախ վերանայում (Linux, C++)

Այնուամենայնիվ, ստատիկ անալիզատորը կարո՞ղ է դա հաշվի առնել: չգիտեմ:

Արդյունքները

PVS-ն իմ բաց կոդով նախագծերում իրական սխալներ չի գտել պայթել и Պրոքսիմա, ինչպես նաեւ աշխատանքային նախագծում, որը հասկանալի պատճառներով չեմ կարող ներկայացնել։ Ճիշտ է, արժե նկատի ունենալ, որ որոշ թերություններ արդեն իսկ հայտնաբերվել և շտկվել են ավելի վաղ օգտագործելով Cppcheck и scan-build.

Ընդհանուր առմամբ, այս բոլոր անալիզատորներից տպավորությունը մոտավորապես նույնն է. այո, նրանք ինչ-որ բան են բռնում, երբեմն նույնիսկ կարևոր, բայց ընդհանուր առմամբ կոմպիլյատորը բավարար է:

Հնարավոր է (և ես անձամբ սիրում եմ այդպես մտածել), որ մեր թիմը օգտագործում է ծրագրային ապահովման մշակման պրակտիկա, որը թույլ է տալիս մեզ ստեղծել նվազագույն քանակի անպիտան կոդ: Ավելի լավ է խնդիրներ չստեղծել, քան հերոսաբար հաղթահարել դրանք։

Հետևաբար, ես ազատություն եմ վերցնում մի քանի խորհուրդ տալ, թե ինչպես գրել C++-ով այնպես, որ ոչ մեկի ոտքերը չկրակեն կամ փոցխով չխփեն որևէ մեկի ճակատին։

Առավելագույնս օգտագործեք կոմպիլյատորների ախտորոշումը

Մեր թիմը օգտագործում է (և ձեզ խորհուրդ է տալիս) հետևյալ կազմման տարբերակները.

-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

Միացրեք դրանք ձեր նախագծում և շատ բան սովորեք ձեր կոդի մասին:

Մնացեք ստանդարտին

Փորձեք չօգտագործել պլատֆորմից կախված բաներ, եթե կան ստանդարտ անալոգներ, և եթե բացարձակապես չեք կարող անել առանց դրանց, փաթեթավորեք դրանք հատուկ բլոկների մեջ մակրոների համար (կամ այլ բան) և պարզապես թույլ մի տվեք, որ ձեր կոդը կազմվի չաջակցվող պայմաններում:

Մնացեք ստանդարտ գործողության իմաստաբանությանը

Գումարը պետք է լինի գումարում, բազմապատկումը պետք է լինի բազմապատկում, ֆունկցիայի կանչը պետք է լինի ֆունկցիայի կանչ, պատճենը պետք է լինի պատճեն, կրելը պետք է լինի կրում, բեռնարկղը պետք է լինի կրկնվող, կրկնողը՝ առաջխաղացում ++ և վերաբերում *. Եվ այլն, և այլն:

Կարծում եմ՝ միտքը պարզ է. Կան հաստատված կոնվենցիաներ, որոնք պարտադիր չեն, բայց որոնք ակնկալում են տեսնել ձեր ծածկագրի բոլոր օգտվողներն ու ընթերցողները: Մի փորձեք ուրիշներին գերազանցել, հակառակ դեպքում դուք ինքներդ ձեզ կխաբեք:

Գրեք համատեղելի կոդ

Առաջին հերթին նկատի ունեմ ստանդարտ գրադարանը։ Շատ ցանկալի է, որ ձեր դասերի և գործառույթների միջերեսները կարող են օգտագործվել ստանդարտ և այլ գրադարանների հետ (օրինակ՝ Boost):

Ազատորեն դիտեք STL և Boost միջերեսները: Հազվագյուտ բացառություններով, դուք այնտեղ կտեսնեք արժանի օրինակելի:

Օգտագործեք բաց կոդով գործիքներից առավելագույնը

Նույն ստատիկ վերլուծության համար կան առնվազն երկու բաց անվճար գործիքներ, որոնք կարող են միայն մեկ անգամ միացվել ցանկացած նախագծի CMake build համակարգով:

Այս մասին ավելին կարող եք կարդալ իմ վերջին հրապարակման մեջ.

Հետո

Ի վերջո, ես կցանկանայի ընդգծել, որ ես չեմ ջատագովում չօգտագործել PVS կամ այլ ստատիկ անալիզատորներ: Բայց ես խրախուսում եմ ձեզ մտածել այն մասին, թե ինչպես է պատահել, որ ստատիկ անալիզատորը անընդհատ զգալի սխալներ է գտնում ձեր կոդում:

Սա ուղղակի հետևանք է։ Պետք է փնտրել և վերացնել պատճառը:

Source: www.habr.com

Добавить комментарий