سؤال

النظر في برنامج C يتكون من ملفين،

F1.c:

int x;

F2.c:

int x=2;

قراءتي للفقرة 6.9.2 من المعيار C99 هو أنه ينبغي رفض هذا البرنامج. في التفسير الخاص بي 6.9.2، متغير x يتم تعريف مبدئيا في f1.c, ، ولكن هذا التعريف المبدئي يصبح تعريفا حقيقيا في نهاية وحدة الترجمة، و (في رأيي)، يجب أن يتصرف كما لو f1.c تضمن التعريف int x=0;.

مع جميع المترجمين (والأهم من ذلك، رابطون) كنت قادرا على المحاولة، هذا ليس ما يحدث. جميع منصات الترجمة التي حاولت القيام بها ربط الملفتين أعلاه، وقيمة x هو 2 في كلا الملفين.

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

أي أفكار حول هذا؟ تفسيرات أخرى من المعيار؟ أسماء منصات على الملفات التي f1.c و f2.c رفض أن تكون مرتبطة معا؟

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

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

المحلول

أنظر أيضا ما هي المتغيرات الخارجية في ج. وبعد يتم ذكر ذلك في المعيار C في الملحق المفيد J كملحق مشترك:

J.5.11 تعاريف خارجية متعددة

قد يكون هناك أكثر من تعريف خارجي واحد لمعرف كائن، مع أو بدون استخدام صريح للكلمة الخارجية الرئيسية؛ إذا كانت التعريفات لا توافق، أو أكثر من واحد تتم تهيئتها، فإن السلوك غير محدد (6.9.2).

تحذير

كما يشير Litb هنا، كما هو مذكور في إجابتي على السؤال المشار إليه المشجعي، باستخدام تعريفات متعددة متغير عالمي يؤدي إلى سلوك غير محدد، وهو طريقة قياسية لقول "أي شيء يمكن أن يحدث". أحد الأشياء التي يمكن أن تحدث هي أن البرنامج يتصرف كما تتوقع؛ و J.5.11 تقول، تقريبا، "قد تكون محظوظا أكثر مما تستحق". لكن برنامج يعتمد على تعريفات متعددة لمتغير خارجي - مع أو بدون كلمة "خارجية" صريحة "- ليس برنامجا مطابقا بدقة وليس مضمونا للعمل في كل مكان. باستثناء: يحتوي على حشرة التي قد تظهر أو لا تظهر نفسها.

نصائح أخرى

هناك شيء يسمى "امتداد مشترك" إلى المعيار، حيث يسمح بتحديد المتغيرات عدة مرات طالما تم تهيئة المتغير مرة واحدة فقط. يرى http://c-faq.com/decl/decldef.html.

تقول هذه الصفحة المرتبطة أن هذا وثائق منصات UNIX - أعتقد أنه هو نفسه بالنسبة ل C99 كما C89 - رغم أنه ربما تم اعتماده من قبل المزيد من المحامصين لتشكيل نوع من معيار Defacto. مثير للانتباه.

هذا هو توضيح إجابتي للتعليق من قبل Olovb:

إخراج NM لملف كائن مترجم من "Int X؛". على هذه المنصة، يتم إضفاء الرموز ب "_"، أي أن المتغير X يظهر مثل _x.

00000000 T _main
         U _unknown
00000004 C _x
         U dyld_stub_binding_helper

إخراج NM لملف كائن مترجم من "Int X = 1؛"

00000000 T _main
         U _unknown
000000a0 D _x
         U dyld_stub_binding_helper

إخراج NM للحصول على ملف كائن مترجم من "INT X = 0؛"

00000000 T _main
         U _unknown
000000a0 D _x
         U dyld_stub_binding_helper

إخراج NM لملف كائن مترجم من "Int Int X؛"

00000000 T _main
         U _unknown
         U dyld_stub_binding_helper

تحرير: إخراج NM لملف كائن مترجم من "Int Int X؛" حيث يتم استخدام x فعلا في واحدة من الوظائف

00000000 T _main
         U _unknown
         U _x
         U dyld_stub_binding_helper
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top