• 0
houssam11350_11350

[تمت الإجابة] تصرف غريب من المترجم gcc

سؤال

السلام عليكم ..

بعد مشاركتي في موضوع الأخ مصطفى (سؤال : هل نعتبر تعليمات الـpreProcessor جزءاً من اللغة ؟)

قمت بتجريب بعض الأكواد التي عملت لها PreProcessing  باستخدام الـــ (C Pre Processor) المسمى cpp  فوجدت انه عندما يقوم باستبدال الــIncludes  بمحتوى الملف الاصلي فإنه يقوم بوضع الرمز # متبوعا برقم السطر و اسم الملف الذي جاء منه الكود : مثل : 

#100 "a.c"

 أي ان الكود التالي لهذا السطر تم جلبه ابتداء من السطر 100 من الملف a.c  و مهمة هذا السطر ان المترجم يعيد لنا اسم الملف الاصلي و رقم السطر الحقيقي عند حصول خطأ .. (طبعا بعد عملية الــ PreProcessing)  تكون أرقام الاسطر في الكود قد تغيرت و عندما تدخل الأكواد للترجمة الفعلية و يكتشف المترجم أن هناك خطأ فإنه يعيد لنا اسم الملف و رقم السطر الحقيقي اعتمادا على المعلومات السابقة التي تم وضعها في مرحلة الــ PreProcessing .

الآن لنجرب الكود التالي  و نحفظه في ملف باسم ab.c: 

#680 "myDoc.pdf"main(){int y}

 و نترجمه (gcc  على Cygwin) , طبعا الكود ينقصه فاصلة منقوطة في السطر الرابع , و لكن المترجم سيعطي الخطأ التالي: 

# gcc  -o ab ab.cmyDoc.pdf: In function ?main?:myDoc.pdf:683: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?}? token

:wacko:  :wacko:  :wacko:

يعطينا رسالة أنه في الملف myDoc.pdf  في السطر 683 يوجد خطأ , علما انه لا يوجد ملف بهذا الاسم و الكود كله على بعضه 5 أسطر .

الذي حصل , أن الــ PreProcessor  قد مرر السطر  : 

#680 "myDoc.pdf"

إلى المترجم (هنا الخطأ , المفروض ان يعترض),  مع باقي الكود , ثم اكتشف المترجم انه لا يوجد فاصلة منقوطة , فسوف يعيد رسالة بالسطر و اسم الملف , للمستخدم , و هو سيأخذه من آخر سطر يبدأ بالرمز # .. الذي هو  (#680 "myDoc.pdf") أي اعتبر أن الكود تم جلبه من الملف MyDoc.pdf  من السطر 680 و سطرنا هو الثالث عمليا , فاعتبره أنه موجود في السطر 683  ..

 

برأيي أن المترجم gcc  كان من المفروض ان لا يتم خداعه بهذه الطريقة .  :)   و انه من البداية يجب ان يعترض على الـــ PreProcessor Directive  الموجود في السطر الأول .

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

2 إجابة على هذا السؤال .

  • 0

فى البداية الإسلوب الذى استخدمته خاطئ و المفترض ان لا يعمل مع الـ preprocessor الموجود داخل ++g بإستخدام (E-)  حيث المفترض لتغيير رقم السطر او الملف يتم إستخدام الشكل التالي:

# line digit-sequence new-line

و ليس

# digit-sequence new-line

فى الواقع المفترض ان اى سطر يبدأ بـ # و لا يتبعه كلمة محجوزه من كلمات الـ preprocessor يعتبر خاطئ أو يتم تجاهله (إصدارتحذير أمر يعود لمصمم المترجم).

 

علما انه لا يوجد ملف بهذا الاسم و الكود كله على بعضه 5 أسطر .

يوجد نوعين من اراقم الأسطر من وجهة نظر الـ preprocessor:

1- source line: و هو رقم السطر داخل ملف الكود الذى قمت انت بكتابته و يسمي ايضا physical line.

2- logical line: و هو رقم السطر بعد حذف الـ line splice (و هى عباره عن علامة backslash يبعها علامة new-line).

 

عندما تستخدم line# فانت تخبره انك تريد عندما تقوم بإظهار رسائل التحذير او الخطأ بأن يظهرها كأن رقم السطر و إسم الملف تبعا لمكان الخطأ أو التحذير كما ذكرت أنت و إذا لم تقم بذكر إسم ملف سيتم إستخدام إسم الملف الذى تم أخذ منه هذا السطر فى رسائل الخطأ و التحذير.

 

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

 

هذا الإسلوب تتبعه العديد من المترجمات عند الترجمه لتسهيل مراحل الترجمه.

 

برأيي أن المترجم gcc  كان من المفروض ان لا يتم خداعه بهذه الطريقة .  :)   و انه من البداية يجب ان يعترض على الـــ PreProcessor Directive  الموجود في السطر الأول .

المفترض ان يظهر رسالة خطأ عند 100 لأنها ليست preprocessor directive.

 

 

و الله ولي التوفيق

2

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخي C++er

شكرا على المعلومات التوضيحية ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .