سؤال

ج يحدد 3 مستويات على الأقل من "التعبير الثابت":

  • التعبير المستمر (غير مؤهل)
  • التعبير الحسابي الثابت
  • تعبير ثابت صحيح

6-6 فيما يلي نص الفقرة 3::

يجب ألا تحتوي التعبيرات الثابتة على تعيين أو زيادة أو إنقاص أو استدعاء وظيفة, أو عوامل الفاصلة ، إلا عندما يتم تضمينها في تعبير فرعي غير موجود تقييم.

فهل هذا يعني 1,2 ليس تعبيرا ثابتا?

وتنص الفقرة 8 على ما يلي::

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

ما هي المعاملات في (union { uint32_t i; float f; }){ 1 }.f?إذا 1 هو المعامل ، فمن المفترض أن يكون هذا تعبيرا حسابيا ثابتا ، ولكن إذا { 1 } هو المعامل ، فمن الواضح أنه ليس كذلك.

تحرير: ملاحظة أخرى مثيرة للاهتمام:7.17 الفقرة 3 تتطلب نتيجة offsetof أن يكون تعبيرا ثابتا صحيحا عن النوع size_t, ، لكن التطبيقات القياسية لـ offsetof, ، بقدر ما أستطيع أن أقول ، ليست مطلوبة لتكون تعبيرات ثابتة صحيحة من قبل المعيار.هذا بالطبع جيد حيث يسمح للتنفيذ (بموجب الفقرة 6.6 10) بقبول أشكال أخرى من التعبيرات الثابتة ، أو تنفيذ offsetof ماكرو أس __builtin_offsetof بدلا من طرح المؤشر.ومع ذلك ، فإن جوهر هذه الملاحظة هو أنه إذا كنت تريد استخدام offsetof في سياق يتطلب تعبيرا ثابتا صحيحا ، تحتاج حقا إلى استخدام الماكرو الذي يوفره التنفيذ وليس لفه بنفسك.

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

المحلول

بناء على قراءتك, 1,2 ليس تعبيرا ثابتا.أنا لا أعرف لماذا ليس كذلك ، فقط أن أتفق معك أنه ليس (على الرغم من حقيقة أنه ربما ينبغي أن يكون).

6.5.2 يحدد الحرفية المركبة كمشغل بوستفيكس.حتى في

(union { uint32_t i; float f; }){ 1 }.f

المعاملات هي (union { uint32_t i; float f; }){ 1 } و f إلى . المشغل.إنه ليس تعبيرا حسابيا ثابتا ، لأن الحجة الأولى هي أ union اكتب ، لكنه تعبير ثابت.

تحديث: كنت أسند هذا على تفسير مختلف للمعيار.

كان منطقي السابق هو ذلك (union { uint32_t i; float f; }){ 1 }.f استوفى معايير التعبير الثابت ، وبالتالي كان تعبيرا ثابتا.ما زلت أعتقد أنه يفي بمعايير التعبير الثابت (6.6 الفقرة 3) ولكنه ليس أيا من الأنواع القياسية للتعبيرات الثابتة (عدد صحيح أو حسابي أو عنوان) وبالتالي فهو يخضع فقط لكونه تعبيرا ثابتا بواسطة 6.6 الفقرة 10 ، مما يسمح بالتعبيرات الثابتة المعرفة بالتنفيذ.

فما استقاموا لكم فاستقيموا أيضا كان معنى للوصول الى تحرير الخاص بك.كنت ذاهبا إلى القول بأن" الإختراق " تنفيذ offsetof كان تعبيرا ثابتا ، لكنني أعتقد أنه نفس ما ورد أعلاه:يفي بمعايير التعبير الثابت (وربما ثابت العنوان) ولكنه ليس تعبيرا ثابتا صحيحا ، وبالتالي فهو غير صالح خارج الفقرة 6.6 10.

نصائح أخرى

إذا 1,2 سيكون تعبيرا ثابتا ، وهذا من شأنه أن يسمح رمز مثل هذا لتجميع:

{ // code        // How the compiler interprets:
  int a[10, 10]; // int a[10];

  a[5, 8] = 42;  // a[8] = 42;
}

أنا لا أعرف ما إذا كان هذا هو السبب الحقيقي, ولكن أستطيع أن أتخيل أن ينبعث منها خطأ لهذا (مشترك?) اعتبر الخطأ أكثر أهمية من الدوران 1,2 في تعبير ثابت.

تحديث:مثل ر.يشير في تعليق ، رمز حول لم يعد خطأ مترجم منذ إدخال فلاس.

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