سؤال

هل هناك طريقة لتحديد استخدام Typedef Integral/Float الذي ينطوي على أي اسم مستعار؟

شيء يعادل (ولكن بنية بدائية):

template < typename T >
struct restrict { T* __restrict data; };

كما هو سؤال ذي صلة ، هل من الممكن أن تسأل GCC ما الذي يحدد الاسم المستعار/لا الاسم المستعار للمؤشر؟

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

المحلول

كما هو مذكور في التعليقات ، فإن العديد من مجمعي C ++ الأحدث يدعمون تنفيذ C99 لنوع التصفيات المؤهلة. حيث restrict ليست كلمة رئيسية محجوزة في C ++ ، يستخدم المجمعون عمومًا __restrict أو __restrict__. كلاهما مجلس التعاون الخليجي و Visual C ++ توثيق هذا بشكل جيد ، مع إشارات صريحة إلى C99.

ينص المعيار C ++ 1998 على أن " typedef يجب ألا ... يتم الجمع بين المحدد في أ محددات التصريح مع أي نوع من المحدد باستثناء أ نوع المحدد"في الأساس ، يجب أن تكون قائمة من محددات الكتابة, ، بما في ذلك الاثنين السيرة الذاتية, const و volatile.

يعرّف C99 typedef بالمثل ، باستثناء أن قائمة التصفيات الخاصة بها تتضمن restrict.

قد يبدو من المعقول توقع دعم مماثل في typedefs ل nondradard __restrict... ولكنك لم تعرف أبدا!

طريقة ذكية وسهلة لاختبار هذا كما يلي:

extern void link_fail();

typedef int *__restrict restricted_int_p;

void test(restricted_int_p a, restricted_int_p b) {
    *a = 1;
    *b = 2;

    if (*a == 2) link_fail();
}

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

لاحظ أنه على الرغم من أن GCC دعمت بناء جملة تقييد منذ الإصدار 3.0 على الأقل ، إلا أنها لم تنفذ التحسينات المناسبة حتى حتى الإصدار 4.5.

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