خطأ في توجيه #line في برنامج التحويل البرمجي Visual C ++

image1.png

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

تاريخ الخطأ والوصف


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

بدأ أحد المستخدمين لدينا بقاعدة رمز كبيرة ترجمة المشروع بالكامل من إصدار Platform Toolset v141 إلى v142 في Visual Studio 2019. بعد ذلك ، في نتائج التحليل ، ظهرت موجة من تحذيرات V002 وأصدرت عدة عشرات من التحذيرات الأخرى إلى أسطر التعليمات البرمجية الخاطئة (خطأ سطر واحد )

يكتشف التشخيص V002 فقط مثل هذه المواقف (ترقيم الخط غير صحيح). يحدث هذا عادةً بسبب وحدات الماكرو متعددة الأسطر أو توجيهات ما قبل المعالجة الأخرى (مثل #pragma). لا تحدث المشكلة في كثير من الأحيان ، ولكن بشكل رئيسي على مترجم من Microsoft. مثل هذه الزيادة في المشاكل في مشروع واحد كانت غير متوقعة ، لأن لم يظهر نظام الاختبار لدينا وجود مثل هذه المشكلة الخطيرة ، وبدأنا في تصحيح المحلل في ملف المستخدم المعالج مسبقًا.

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

#define MACRO(a, b)              // line1
                                 // line2
int main(int argc, char* argv[]) // line3
{                                // line4
    MACRO("Some string",         // line5
        42);                     // line6
    return 0;                    // line7 <=
}

الملف المعالج كالتالي:

#line 1 "D:\\_Tests\\TestApp\\Project2\\rnd_bs.cpp"


int main(int argc, char* argv[])
{
  ;
#line 8 "D:\\_Tests\\TestApp\\Project2\\rnd_bs.cpp"
  return 0;
}

في بيان عودة هو على 7TH خط في الملف المصدر، ونقاط المعالج إلى 8TH الخط. حدث هذا الخطأ في المعالج الأولي ، ويفترض أنه بسبب ماكرو متعدد الأسطر.

الافراج عن نسخة الإصدار


في وقت كتابة هذا التقرير ، كانت المشكلة ذات صلة بأحدث إصدارات Visual Studio ، حتى الإصدار 16.4.3 (بتاريخ 14 يناير 2020). لقد فتحنا تقرير الخطأ " توجيه #line غير صالح بعد المعالجة المسبقة (VS2019 ، v142) " وبعد 4 أيام من تلقي إجابة مثيرة للاهتمام:

تم تحديد هذه المشكلة على أنها تكرار لتعليقات سابقة تم الإبلاغ عنها مرتبطة هنا: developercommunity.visualstudio.com/content/problem /738407/preprocessor-generates-incorrect-line-information.html . إذا أبلغت أو صوتت هنا ، فقد تم تطبيق تصويتك على المشكلة الأصلية. يمكن لأي شخص آخر إضافة تصويتهم مباشرة على التعليقات المرتبطة أعلاه. يساعد التصويت على زيادة أولوية المشكلة من خلال دمج تأثير العملاء ضمن تعليق واحد. شكرا لك!

اتضح أنه تم الإبلاغ عن هذه المشكلة بالفعل ، وفي 18 سبتمبر 2019 - قبل نصف عام تقريبًا: " يولد المعالج المسبق معلومات خط غير صحيحة ". قدم المستخدم أمثلة رمز مشابهة لإعادة إنتاج الخطأ. وفقًا للمؤلف ، يوجد الخطأ على الأقل مع Visual Studio 2019 16.2.

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

في 19 مايو 2020 ، تم إصدار إصدار ثابت من Visual Studio 2019 16.6.0. نوصي جميع مستخدمي PVS-Studio بالتبديل إليه.


إذا كنت ترغب في مشاركة هذه المقالة مع جمهور يتحدث الإنجليزية ، فيرجى استخدام رابط الترجمة: Svyatoslav Razmyslov. خطأ أحدثه #line Directive في برنامج التحويل البرمجي Visual C ++ .

All Articles