• 0
محمد علاء الدين

فكر معي فى قيمة هذين المتغيرين

سؤال

فلنقترض أن لديك الملف A.cc و يحتوى على الكود التالي:


// A.cc

extern int value2;
int value1 = value2 + 10;

أيضا لديك الملف B.cc و يحتوى على الكود التالي:


// B.cc

extern int value1;
int value2 = value1 + 10;

السؤال ببساطه ما هي قيمة كل من value1 و value2 و لماذا؟ :cool:

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

تم تعديل بواسطه محمد علاء الدين
1

شارك هذا الرد


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

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

  • 0

الكثير من التوقعات و الافكار, اظن انها ستكون infinite loop و ستكون مثل ال Recursion لكن لن تعطيك ناتج و سيهظر خطاء ما....

هذا و الله اعلم :D

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
الكثير من التوقعات و الافكار, اظن انها ستكون infinite loop و ستكون مثل ال Recursion لكن لن تعطيك ناتج و سيهظر خطاء ما....

الكود سليم 100% و لا يحتوي على أخطأ و سيتم تنفيذه بنجاح، و يبقي السؤال كما هو:

ما هي قيمة كل من value1 و value2 و لماذا؟

0

شارك هذا الرد


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

البرنامج خاطئ undefined behavior, لأنك تعتمد على عمل initialization لمتغير بقيمة متغير قيمته لم تحدد بعد. هذا ينشأ لأنك اعتمدت على unspecified behavior بحيث أن المترجم له الحق في تنفيذ أي من السطرين التاليين بالترتيب الذي يراه أنسب لأن كل سطر عبارة عن عملية global initialization

 int value1 = value2 + 10;

int value2 = value1 + 10;

هناك طرق عديدة لتنفيذ ما تريد بدون مشاكل, و لكن هذه الطريقة خاطئة.

بالمناسبة هذا الأمر يطلق عليه static initialization order fiasco!

تم تعديل بواسطه Khaled.Alshaya
1

شارك هذا الرد


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

أهلا خالد نورت الموضوع، أشتقت للنقاش معاك.

المترجم له الحق في تنفيذ أي من السطرين التاليين بالترتيب الذي يراه أنسب لأن كل سطر عبارة عن عملية global initialization

لاحظ أن كل من التعريفين يتضمن external linkage و بالتالي عملية تحديد قيمة كل من المتغيرين تعتمد على الـ linker و ليس المترجم و حيث ان نوع كل من المتغيرين هو primitive type سيتم تحديد القيمه الإفتراضيه بصفر و لكن لن يتم تحديدها إلا من خلال الـ linker حيث إذا قمت بتمرير الـ A.obj اولا للـ linker يليه B.obj حينها ما سيحدث هو جعل قيمة value2 بصفر مما يجعل قيمة value1 تساوي 10 و بالتبعيه يجعل قيمة value2 تساوي 20، و العكس سيحدث إذا قمت بتبديل ترتيب الـ object file عند تمريرهم للـ linker.

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

2

شارك هذا الرد


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

وضعت سؤالاً حول الموضوع في Stackoverflow لعلنا نجد توضيح :)

http://stackoverflow.com/questions/5986668/does-this-code-produce-undefined-behavior-or-it-is-merely-unspecified-behavior

تحياتي...

0

شارك هذا الرد


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

إذا اردت إجابه أكثر تفصيلا راجع كتاب Thinking in C++, 2nd Edition، الفصل العاشر Name Control، الفقره Static initialization dependency المثال الثاني، ستجده شبيها بالمثال الذى وضعته هنا.

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

1

شارك هذا الرد


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

جميل, في الحقيقة اعتقدت أن الكود سيؤدي إلى undefined behavior و لكن في الحقيقة يبقى الأمر unspecified فقط.

تحياتي أخي محمد,

1

شارك هذا الرد


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

موضوع رائع ونقاش أروع كالعادة

شكرا لك اخى محمد

تحياتى

0

شارك هذا الرد


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

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

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

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