c & c++ الارتباط المتغير العام الافتراضي، مشكلة الإعلان والتعريف المتعددة

StackOverflow https://stackoverflow.com/questions/6371048

سؤال

على سبيل المثال:

code1.c / .cpp

int a;

// ... and so on

code2.c / .cpp

int a;

int main(void) {
    return 0;
}

اذهب لتجميع:

$gcc code1.c code2.c      # this is fine
$

$g++ code1.cpp code2.cpp  # this is dead
/tmp/ccLY66HQ.o:(.bss+0x0): multiple definition of `a'
/tmp/ccnIOmPC.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

هل هناك أي فرق عالمي في الارتباط المتغير بين C & C++؟

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

المحلول

انها ليست قانونية بشكل صارم. int a; هو تعريف مؤقت في C.يُسمح لك بتعريفات مؤقتة متعددة وتعريف واحد غير مؤقت على الأكثر لكل وحدة ترجمة لكل كائن له رابط خارجي في لغة C، ولكن تعريف واحد فقط عبر جميع وحدات الترجمة في البرنامج.

وهو امتداد يتم تنفيذه بشكل شائع للسماح بالتعريفات المؤقتة عبر وحدات ترجمة متعددة في لغة C طالما أنه لا تحتوي أكثر من وحدة ترجمة واحدة على تعريف غير مؤقت، ولكنه ليس معيارًا صارمًا.

في لغة سي++ int a; هو مجرد تعريف - لا يوجد مفهوم مؤقت - ولا يزال من غير القانوني الحصول على تعريفات متعددة لكائن ما عبر وحدات الترجمة للبرنامج.

بالنسبة لحالة C، قد ترغب في إلقاء نظرة عليها هذا السؤال.

نصائح أخرى

يعد هذا مخالفًا للقانون في كليهما ، ولكن مترجمي لغة سي ينفذون امتدادًا بشكل عام.راجع هذه الإجابة .

هناك ثلاث طرق لحل المشكلة:

  1. إذا متغير a هو نفسه في كلا الملفين، يجب أن تعلن أنه extern في كافة الملفات باستثناء ملف واحد. extern تقول الكلمة الأساسية للرابط أن هذا الاسم موجود في ملفات أخرى.

  2. يمكنك استخدام static الكلمة الأساسية للحد من نطاق المتغير إلى ملف واحد.التي أعلن فيها.

  3. أو يمكنك استخدام مساحة الاسم بدون اسم.

يعتبر برنامج التحويل البرمجي g ++ أكثر صرامة من مترجم gcc. يعتمد هذا أيضًا على إصدار دول مجلس التعاون الخليجي ، وقد يكون الإصدار الأعلى من مجلس التعاون الخليجي ، أي 4.x وما بعده ، يمكن أن يؤدي إلى نفس الخطأ.

استخدم رمز الترميز العام لتجنب

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