مراجعة مستقلة لبرنامج 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.

لغة

جميع الأوصاف باللغة الروسية، وهو أمر عظيم. لكن الروابط الموجودة في التقرير تؤدي دائمًا إلى النسخة الإنجليزية. سيكون من الجيد أن تكون قادرًا على تبديل اللغة حتى تتمكن من عرض التشخيص على الفور باللغة الروسية. لم أجد مثل هذا الخيار في الواجهة.

من غير الملائم العمل مع مستويات التشخيص عبر وحدة التحكم

لنبدأ بحقيقة أن الأمرين المستخدمين (this 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

ظهرت هنا بعض "المستويات" التي لم تكن موجودة من قبل، ولم أجد شيئًا عنها في الوثائق أيضًا.

بشكل عام، فإنه ليس واضحا. لهذا السبب قمت بتعيين كل شيء إلى الحد الأقصى.

حفنة من الشتائم الغبية على الصيد

يستخدم اثنان من المشاريع الثلاثة التي قمت بتحليلها مكتبة اختبار الوحدة 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.

يمكنك قراءة المزيد عن هذا في منشوري الأخير.

خاتمة

أخيرًا، أود التأكيد على أنني لا أدعو إلى عدم استخدام PVS أو أي محلل ثابت آخر. لكنني أشجعك على التفكير في كيفية اكتشاف المحلل الثابت باستمرار لأخطاء كبيرة في التعليمات البرمجية الخاصة بك.

هذه مجرد نتيجة. نحن بحاجة للبحث عن السبب والقضاء عليه.

المصدر: www.habr.com

إضافة تعليق