سيؤدي التحليل الثابت إلى تحسين قاعدة الكود الخاصة بمشاريع C ++ المعقدة

المشاريع الكبيرة القديمة

تدريجيا وبشكل غير واضح ، يتطور الموقف عندما يصبح تعقيد مشاريع C ++ الخطيرة باهظًا. لسوء الحظ ، الآن لا يمكن للمبرمج C ++ الاعتماد فقط على نقاط القوة الخاصة به.

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

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

هل الوضع ميئوس منه؟ لا. تأتي فئة جديدة من الأدوات في عملية الإنقاذ: أجهزة تحليل الشفرات الثابتة. كثير من المبرمجين ذوي الخبرة في هذه اللحظة كرة لولبية شفاههم ، كما لو أنها تراجعت الليمون :). مثل ، نحن نعرف هذه الأشياء الخاصة بك ... هناك الكثير من الرسائل ، القليل من ... نعم ، وما هي هذه الفئة الجديدة من الأدوات؟! نحن linter أطلقت منذ 20 عاما.

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

هذه ليست كلمات مجردة ، لكنها حقيقة أراها كأحد منشئي أداة PVS-Studio. تحقق من هذه المقالة لمعرفة لماذا يمكن للمحللين العثور على أخطاء مثيرة للاهتمام.

ومع ذلك ، فمن الأهمية بمكان أن يكون للمحللات الساكنة الحديثة معرفة واسعة بأنماط الخطأ. علاوة على ذلك ، يعرف المحللون أكثر من المطورين المحترفين. أصبح من الصعب للغاية أن تأخذ في الاعتبار وتذكر جميع الفروق الدقيقة عند كتابة التعليمات البرمجية. على سبيل المثال ، ما لم تقرأ حول هذا الموضوع بالتحديد في مكان ما ، فلن تخمن أبدًا أن المكالمات إلى وظيفة memset لمسح البيانات الخاصة تختفي أحيانًا ، نظرًا لأن من وجهة نظر المترجم ، تكون الدعوة إلى وظيفة memset متكررة. وفي الوقت نفسه ، هذا عيب أمني خطير CWE-14 ، والذي يوجد حرفيًا في كل مكان . أو من يعرف ، على سبيل المثال ، ما هو الخطورة في ملء الحاوية؟

std::vector<std::unique_ptr<MyType>> v; v.emplace_back(new MyType(123)); 

أعتقد أنه لن يدرك الجميع على الفور أن مثل هذا الرمز قد يكون خطيرًا ويمكن أن يؤدي إلى تسرب الذاكرة.

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

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

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

قد يقول أحدهم أنه لا يوجد أي نقطة في الأدوات الخاصة ، لأن المترجم يتعلم أيضًا إجراء مثل هذه الاختبارات الثابتة. نعم هو كذلك. ومع ذلك ، بطبيعة الحال ، لا يقف المحللون الثابتون ثابتًا وكيف تتفوق الأدوات المتخصصة على المترجمين. على سبيل المثال ، في كل مرة نتحقق فيها من LLVM ، نجد أخطاء هناك باستخدام PVS-Studio.

يقدم العالم عددًا كبيرًا من الأدوات لتحليل الكود الثابت. كما يقولون ، اختر لذوقك. هل تريد العثور على الكثير من الأخطاء ونقاط الضعف المحتملة حتى في مرحلة كتابة التعليمات البرمجية؟ استخدام محللات الكود الثابت وتحسين جودة قاعدة الكود الخاصة بك!



إذا كنت ترغب في مشاركة هذا المقال مع جمهور يتحدث الإنجليزية ، فالرجاء استخدام هذا الرابط: Andrey Karpov. لماذا التحليل الثابت يمكن تحسين C ++ معقدة Codebase

Source: https://habr.com/ru/post/ar462399/


All Articles