رأيت المنشور الذي تعلمته PVS التحليل في نظام Linux ، وقررت تجربة مشروعاته. وهذا ما جاء منه.
محتوى
- الأشياء الجيدة
- سلبيات
- النتائج
- خاتمة
دعم استجابة
طلبت مفتاح تجريبي ، أرسلوه لي في نفس اليوم.
مسح وثائق كافية
كان من الممكن بدء المحلل دون أي مشاكل. تتوفر أيضًا تعليمات لأوامر وحدة التحكم (على الرغم من وجود شكاوى ، راجع قسم سلبيات ).
القدرة على تحليل متعدد الخيوط
لدى المحلل خيار "قياسي" -j
، والذي يسمح بالتحليل بالتوازي في العديد من المهام. هذا يوفر الكثير من الوقت.
التصور الجيد
العديد من تنسيقات الإخراج المختلفة ، من النص إلى كمامة الويب الصغيرة. يعد وجه الويب مريحًا وموجزًا ، حيث توجد نصائح بجانب الأسطر الموجودة في التعليمات البرمجية وروابط لأوصاف التشخيص .
تكامل سهل التجميع
جميع الوثائق موجودة على موقعه على الويب ، لا يمكنني إلا أن أقول إنه إذا تم بناء مشروعك باستخدام CMake ، فكل شيء بسيط للغاية.
أوصاف تشخيصية جيدة
إذا قمت بإنشاء مخرجات في وضع fullhtml
، فإن كل رسالة تحتوي على رابط لوصف التشخيص ، مع تقديم توضيحات وأمثلة رمز وروابط إضافية.
ج + محلل اللغة الجهل
لسوء الحظ ، يخطئ 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 بوابة المهلة .
لغة
كل الأوصاف باللغة الروسية ، هذا رائع. لكن الروابط الواردة في التقرير تؤدي دائمًا إلى إصدار اللغة الإنجليزية. سيكون من الجيد أن تكون قادرًا على تبديل اللغة حتى تتمكن من عرض التشخيصات باللغة الروسية على الفور. لم أجد هذه الفرصة في الواجهة.
غير مريح للعمل مع مستويات التشخيص من خلال وحدة التحكم
بادئ ذي بدء ، يكون لدى الأمرين ( pvs-studio-analyzer
plog-converter
و 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
عادة ما يكون استخدام bitmasks في واجهات المستخدم فكرة سيئة. كل هذا يمكن تلخيصه في الداخل ، ووضع المستخدم مجموعة من الأعلام.
بالإضافة إلى ذلك ، هناك أيضًا أداة plog-converter
، التي تنشئ معلومات يمكن قراءتها من قبل الإنسان حول التحليل الثابت. لديها مشاكل أخرى.
تعليمات plog-converter
برنامج plog-converter
:
-a, --analyzer Specifies analyzer(s) and level(s) to be used for filtering, ie 'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2' Default: GA:1,2
ظهر نوع من "المستويات" هنا ، لم يسبق له مثيل من قبل ، ولم أجد شيئًا عنها في الوثائق.
بشكل عام ، ليس واضحا. لذلك ، أنا وضعت كل شيء إلى الحد الأقصى.
حفنة من اليمين الدستورية الغبية في كاتش
اثنين من المشاريع الثلاثة التي قمت بتحليلها استخدم مكتبة اختبار وحدة Catch2 . وحصة الأسد من الرسائل (!!! 90 من 138 في واحد و 297 من 344 في آخر !!!) يكون بالشكل التالي:

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

ومع ذلك ، يمكن للمحلل ثابت تأخذ هذا في الاعتبار على الإطلاق؟ لا اعرف
لم تجد PVS خطأ حقيقيًا واحدًا في مشروعي المفتوح Burst and Proxima ، وكذلك في مسودة عمل ، لا يمكنني تقديمها لأسباب واضحة. صحيح ، يجب أن يؤخذ في الاعتبار أن بعض العيوب تم اكتشافها وإصلاحها مسبقًا باستخدام 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
شملهم في مشروعك ، وتعلموا الكثير عن الكود.
التمسك المعيار
حاول ألا تستخدم الأشياء التي تعتمد على النظام الأساسي إذا كان هناك نظائر قياسية ، وإذا لم يكن بإمكانك الاستغناء عنها على الإطلاق ، فلفها في كتل خاصة من أجل لقطات الماكرو (أو أي شيء آخر) ولا تدعنا نجمع الشفرة في ظروف غير مدعومة.
التمسك دلالات التشغيل القياسية
يجب أن تكون الإضافة هي الإضافة ، الضرب بالضرب ، استدعاء الوظيفة بالدعوة الوظيفية ، النسخ يجب نسخها ، يجب نقل النقل ، يجب أن تكون الحاوية قابلة للتكرار ، يجب أن يكون لدى أداة التكرار ++
ترقية و dereference *
. وهلم جرا وهكذا دواليك.
أعتقد أن الفكرة واضحة. هناك اتفاقيات ثابتة غير ملزمة ولكن يتوقع جميع مستخدميها وقارئات الشفرة رؤيتها. لا تحاول التغلب على الآخرين ، أو تفوق على نفسك.
اكتب كود متوافق
بادئ ذي بدء ، أعني المكتبة القياسية. من المرغوب فيه للغاية استخدام واجهات الفئات والوظائف الخاصة بك مع المكتبات القياسية وغيرها من المكتبات (على سبيل المثال ، تمثال نصفي).
لا تتردد في إلقاء نظرة خاطفة على واجهات STL و Boost. مع استثناءات نادرة ، سترى نموذجًا يستحق الدور هناك.
الاستفادة القصوى من الأدوات المفتوحة
لنفس التحليل الثابت ، يوجد على الأقل اثنين من الأدوات المجانية المفتوحة المتصلة بأي مشروع مع نظام بناء CMake على حساب "الوقت".
يمكنك قراءة المزيد حول هذا الموضوع في منشوري الأخير .
في الختام ، أؤكد أنني لا أحث على عدم استخدام PVS أو أي محلل ثابت آخر. لكني أحثك على التفكير في الكيفية التي تبين بها أن المحلل الثابت يكتشف باستمرار أخطاء كبيرة في الكود.
هذه ليست سوى نتيجة. من الضروري البحث والقضاء على السبب.