ما هي القواعد المتعلقة باستخدام الشرطة السفلية في معرف C++؟

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

سؤال

من الشائع في لغة C++ تسمية متغيرات الأعضاء بنوع من البادئة للإشارة إلى حقيقة أنها متغيرات أعضاء، وليست متغيرات أو معلمات محلية.إذا كنت قادمًا من خلفية MFC، فمن المحتمل أن تستخدم m_foo.لقد رأيت أيضا myFoo أحياناً.

يبدو أن لغة C# (أو ربما .NET فقط) توصي باستخدام شرطة سفلية فقط، كما في _foo.هل هذا مسموح به بموجب معيار C++؟

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

المحلول

القواعد (التي لم تتغير في C++ 11):

  • محفوظة في أي نطاق، بما في ذلك للاستخدام تطبيق وحدات الماكرو:
    • المعرفات التي تبدأ بشرطة سفلية متبوعة مباشرة بحرف كبير
    • المعرفات التي تحتوي على الشرطة السفلية المجاورة (أو "الشرطة السفلية المزدوجة")
  • محجوزة في مساحة الاسم العالمية:
    • المعرفات التي تبدأ بشرطة سفلية
  • وكذلك كل ما في std مساحة الاسم محجوزة.(مع ذلك، يُسمح لك بإضافة تخصصات القالب.)

من معيار C++ لعام 2003:

17.4.3.1.2 الأسماء العالمية [lib.global.names]

يتم دائمًا حجز مجموعات معينة من الأسماء وتوقيعات الوظائف للتنفيذ:

  • كل اسم يحتوي على شرطة سفلية مزدوجة (__) أو يبدأ بشرطة سفلية متبوعة بحرف كبير (2.11) محجوز للتنفيذ لأي استخدام.
  • يتم حجز كل اسم يبدأ بشرطة سفلية للتنفيذ لاستخدامه كاسم في مساحة الاسم العامة.165

165) هذه الأسماء محجوزة أيضًا في مساحة الاسم ::std (17.4.3.1).

نظرًا لأن C++ تعتمد على معيار C (1.1/2، C++03) وC99 هو مرجع معياري (1.2/1، C++03)، فإن هذه تنطبق أيضًا، من معيار C لعام 1999:

7.1.3 المعرفات المحجوزة

يعلن كل رأس أو يعرّف جميع المعرفات المدرجة في جماعيه الفرعية المرتبطة بها ، ويعلن اختياريًا أو يحدد المعرفات المدرجة في اتجاهات المكتبة المستقبلية المرتبطة بها التي يتم حجزها معرفاتها دائمًا إما لأي استخدام أو للاستخدام كمعرفات نطاق الملفات.

  • جميع المعرفات التي تبدأ مع السطح السفلي وأحرف كبيرة أو غيرها محفوظة دائمًا لأي استخدام.
  • يتم دائمًا حجز جميع المعرفات التي تبدأ مع السطح السفلي للاستخدام كمعرفات مع نطاق الملف في كل من المساحات العادية والعلامة.
  • يتم حجز كل اسم ماكرو في أي من عمليات النقل الفرعية التالية (بما في ذلك اتجاهات المكتبة المستقبلية) للاستخدام كما هو محدد إذا تم تضمين أي من الرؤوس المرتبطة بها ؛ما لم ينص صراحة على خلاف ذلك (انظر 7.1.4).
  • جميع المعرفات ذات الارتباط الخارجي في أي من عمليات النقل الفرعية التالية (بما في ذلك اتجاهات المكتبة المستقبلية) مخصصة دائمًا للاستخدام كمعرفات ذات ارتباط خارجي.154
  • يتم حجز كل معرف مع نطاق الملف المدرج في أي من عمليات النقل الفرعية التالية (بما في ذلك اتجاهات المكتبة المستقبلية) للاستخدام كاسم ماكرو وكمعرف مع نطاق الملف في نفس المساحة الاسم إذا تم تضمين أي من الرؤوس المرتبطة بها.

لا يتم حجز أي معرفات أخرى.إذا أعلن البرنامج أو يحدد معرفًا في سياق يتم حجزه فيه (بخلاف ما يسمح به 7.1.4) ، أو يحدد معرفًا محجوزًا كاسم ماكرو ، فإن السلوك غير محدد.

إذا قام البرنامج بإزالة (مع #undef) أي تعريف ماكرو لمعرف في المجموعة الأولى المذكورة أعلاه ، فإن السلوك غير محدد.

154) تتضمن قائمة المعرفات المحجوزة ذات الارتباط الخارجي errno, math_errhandling, setjmp, ، و va_end.

قد يتم تطبيق قيود أخرى.على سبيل المثال، يحتفظ معيار POSIX بالكثير من المعرفات التي من المحتمل أن تظهر في الكود العادي:

  • الأسماء التي تبدأ بحرف كبير E اتبعت رقمًا أو حرفًا كبيرًا:
    • يمكن استخدامها لأسماء رموز الخطأ الإضافية.
  • الأسماء التي تبدأ بأي منهما is أو to متبوعًا بحرف صغير
    • يمكن استخدامها لاختبار الأحرف الإضافية ووظائف التحويل.
  • الأسماء التي تبدأ بـ LC_ متبوعًا بحرف كبير
    • يمكن استخدامها لوحدات الماكرو الإضافية التي تحدد سمات اللغة.
  • أسماء جميع وظائف الرياضيات الموجودة ملحقة بـ f أو l محجوزة
    • للوظائف المقابلة التي تعمل على الوسائط العائمة والمزدوجة الطويلة، على التوالي.
  • الأسماء التي تبدأ بـ SIG متبوعًا بحرف كبير محجوزة
    • لأسماء الإشارة الإضافية.
  • الأسماء التي تبدأ بـ SIG_ متبوعًا بحرف كبير محجوزة
    • لإجراءات إشارة إضافية.
  • الأسماء التي تبدأ بـ str, mem, ، أو wcs متبوعة بحرف صغير محجوزة
    • لوظائف السلسلة والصفيف الإضافية.
  • الأسماء التي تبدأ بـ PRI أو SCN متبوعًا بأي حرف صغير أو X محجوزة
    • للحصول على وحدات ماكرو محددة للتنسيق الإضافي
  • الأسماء التي تنتهي بـ _t محجوزة
    • لأسماء الأنواع الإضافية.

على الرغم من أن استخدام هذه الأسماء لأغراضك الخاصة الآن قد لا يسبب مشكلة، إلا أنها تزيد من احتمالية التعارض مع الإصدارات المستقبلية من هذا المعيار.


أنا شخصياً لا أبدأ المعرفات بشرطات سفلية.إضافة جديدة إلى قاعدتي:لا تستخدم الشرطة السفلية المزدوجة في أي مكان، وهو أمر سهل لأنني نادرًا ما أستخدم الشرطة السفلية.

بعد إجراء بحث حول هذه المقالة، لم أعد أنهي معرفاتي بها _tلأن هذا محجوز بواسطة معيار POSIX.

القاعدة المتعلقة بأي معرف ينتهي بـ _t فاجأني كثيرا.أعتقد أن هذا هو معيار POSIX (لست متأكدًا بعد) يبحث عن توضيح وفصل وآية رسميين.هذا من دليل جنو ليبتوول, ، قائمة الأسماء المحجوزة.

قدم CesarB الرابط التالي ل بوسيكس 2004 الرموز والملاحظات المحجوزة "أن العديد من البادئات واللاحقات المحجوزة الأخرى ...يمكن العثور عليها هناك".البوسيكس 2008 يتم تعريف الرموز المحجوزة هنا.القيود أكثر دقة إلى حد ما من تلك المذكورة أعلاه.

نصائح أخرى

قواعد تجنب تضارب الأسماء موجودة في معيار C++ (راجع كتاب Stroustrup) وقد ذكرها معلمو C++ (Sutter، وما إلى ذلك).

القاعدة الشخصية

ولأنني لم أرغب في التعامل مع الحالات، وأردت قاعدة بسيطة، فقد قمت بتصميم ملف شخصي واحد بسيط وصحيح:

عند تسمية رمز، سوف تتجنب الاصطدام مع مكتبات المترجم/نظام التشغيل/المكتبات القياسية إذا كنت:

  • لا تبدأ أبدًا رمزًا بشرطة سفلية
  • لا تقم أبدًا بتسمية رمز به شرطتان سفليتان متتاليتان بداخله.

بالطبع، يساعد وضع التعليمات البرمجية الخاصة بك في مساحة اسم فريدة على تجنب الاصطدام أيضًا (لكنه لن يحمي من وحدات الماكرو الشريرة)

بعض الأمثلة

(أستخدم وحدات الماكرو لأنها أكثر تلويثًا للتعليمات البرمجية لرموز C/C++، ولكنها يمكن أن تكون أي شيء بدءًا من اسم المتغير إلى اسم الفئة)

#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT

مقتطفات من مسودة C++ 0x

من n3242.pdf file (أتوقع أن يكون النص القياسي النهائي مشابهًا):

17.6.3.3.2 الأسماء العالمية [global.names]

يتم دائمًا حجز مجموعات معينة من الأسماء وتوقيعات الوظائف للتنفيذ:

— كل اسم يحتوي على شرطة سفلية مزدوجة _ _ أو يبدأ بشرطة سفلية متبوعة بحرف كبير (2.12) محجوز للتنفيذ لأي استخدام.

— كل اسم يبدأ بشرطة سفلية محجوز للتنفيذ لاستخدامه كاسم في مساحة الاسم العامة.

لكن أيضا:

17.6.3.3.5 اللواحق الحرفية المعرفة من قبل المستخدم [usrlit.suffix]

يتم حجز معرفات اللاحقة الحرفية التي لا تبدأ بشرطة سفلية للتوحيد القياسي في المستقبل.

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

MSDN :

<اقتباس فقرة>   

واستخدام حرفين تسطير متتابعة (__) في بداية معرف، أو قيادي واحد تؤكد يليه حرف، محجوز لتطبيقات C ++ في جميع نطاقات. يجب تجنب استخدام الرائدة واحدة تؤكد يليه حرف صغير للأسماء مع نطاق ملف بسبب الصراعات المحتملة مع معرفات الحالية أو المستقبلية محفوظة.

وهذا يعني أنه يمكنك استخدام تسطير واحد عضوا بادئة متغيرة، طالما انها تبع ذلك رسالة من الحالة الأدنى.

ويبدو يؤخذ هذا من باب 17.4.3.1.2 من المعيار C ++، ولكن لا يمكنني العثور على المصدر الأصلي للمعيار الكامل عبر الإنترنت.

وانظر أيضا هذا السؤال .

وأما بالنسبة للجزء الآخر من السؤال، فإنه من الشائع لوضع تسطير في نهاية من اسم المتغير لعدم الصدام مع أي شيء الداخلي.

وI القيام بذلك حتى الطبقات الداخلية و مساحات الأسماء لأنني ثم لا تملك إلا أن نتذكر قاعدة واحدة (مقارنة ب "في نهاية اسم النطاق العالمي، وبداية من اسم أي مكان آخر").

نعم، يمكن استخدام أحرف (_) في أي مكان في معرف. وأعتقد أن القواعد هي: أي من a-z و A-Z، _ في الحرف الأول وأولئك + 0-9 لمتابعة الأحرف

البادئات

وتؤكد شائعة في التعليمات البرمجية C - لتسطير واحد يعني "الخاص"، وسفلية مزدوجة محجوزة عادة للاستخدام من قبل المجمع

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