سؤال

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

أنا أعرف: لا ينبغي تعريف المتغيرات في ملفات .h. لا بأس أن أعلنهم هناك.

لماذا: لأن ملف الرأس قد يتضمن من أماكن متعددة، وبالتالي إعادة تعريف المتغير أكثر من مرة واحدة (رابط يعطي الخطأ).

من الممكن العمل حول العمل: استخدم Header-Greard في ملفات الرأس وتحديد المتغير في ذلك.

هل هو حقا الحل: لا. لأن حراس الرأس لمرحلة المعالجة المسبقة. هذا هو معرفة التحويل البرمجي أن هذا الجزء قد تم تضمينه بالفعل ولا يشمله مرة أخرى. لكن خطأ التعريف المتعدد لدينا يأتي في الجزء الرابط - الكثير بعد التجميع.

لقد جعلني هذا الأمر كله مشوشا حول كيفية عمل مسبق العمل والربط. اعتقدت أن المعالجة المسبقة لن تتضمن التعليمات البرمجية، إذا تم تعريف رمز حارس الرأس. في هذه الحالة، لا ينبغي حل تعريف متعددة لمشكلة متغيرة أيضا؟

ما يحدث أن هذه التوجيهات المعالجة المسبقة هذه حفظ عملية التجميع من إعادة تعريف الرموز تحت حراس الرأس، ولكن الرابط لا يزال يحصل على تعريفات متعددة للرمز؟

هل كانت مفيدة؟

المحلول

يحميك حارس الرأس من شامل متعددة في ملف مصدر واحد، وليس من ملفات مصدر متعددة. أعتقد أن مشكلتك تنبع من عدم فهم هذا المفهوم.

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

نصائح أخرى

شيء واحد استخدمته في الماضي (عندما كانت المتغيرات العالمية في رواج):

ملف var.h:

...
#ifdef DEFINE_GLOBALS
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int global1;
EXTERN int global2;
...

ثم في واحد ملف .c (عادة ما يحتوي على واحد ()):

#define DEFINE_GLOBALS
#include "var.h"

ما تبقى من ملفات المصدر يشمل فقط "var.h" بشكل طبيعي.

لاحظ أن Define_Globals ليس حارس رأس، بل يسمح بإعلان / تحديد المتغيرات اعتمادا على ما إذا كان يتم تعريفه. تتيح هذه التقنية نسخة واحدة من الإعلانات / التعريفات.

لديك اثنين من ملفات .c. يحصلون على جمعت بشكل منفصل. وبعد كل واحد يشمل ملف الرأس الخاص بك. مرة واحدة. كل واحد يحصل على تعريف. انهم يتعارضون في الوقت الرابط.

الحل التقليدي هو:

#ifdef DEFINE_SOMETHING
int something = 0;
#endif

ثم أنت #Define define_Something في واحد فقط ملف .c.

حراس الرأس توقفوا عن ملف رأس يتم تضمين عدة مرات في نفس وحدة الترجمة (أي في نفس ملف المصدر. ليس لديهم أي تأثير إذا قمت بتضمين الملف في وحدات ترجمة اثنين أو أكثر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top