سي++11
الإضافات لنواة لغة السي++ > تحسينات أداء نواة اللغة لوقت التنفيذ > التعبيرات الثابتة المعممة - constexpr

دائما ما كان لدى السي++ مفهوم التعبيرات الثابتة constant expression. هذه التعبيرات مثل 3+4 تعطي نفس النتيجة دائماً، في وقت الترجمة compile time وفي وقت التنفيذ run time. تعد التعبيرات الثابتة من فرص التحسين للمترجمات، حيث تقوم المترجمات غلباً بتنفيذها في وقت الترجمة وتضع النتيجة بدلاً من التعبير نفسه في البرنامج. أيضا في كثير من الأماكن تتطلب مواصفات سي++ استخدام التعبيرات الثابتة. فتعريف مصفوفة يتطلب تعبير ثابت وقيم القائمة العددية enumerator يجب أن تكون تعبيرات ثابتة.
ومع ذلك فإن التعبيرات الثابتة لم تسمح أبداً باستدعاء دالة أو مشيد لكائن. لذلك فإن مجموعة الأوامر البسيطة التالية غير مقبولة:
int get_five() {return 5;}

int some_value[get_five() + 7]; // إنشاء مصفوفة من 12 عنصر، غير مقبول في السي بلس بلس
ذلك لم يكن مقبول في سي++03 لأن get_five() + 7 ليست تعبير ثابت. مترجم سي++03 لم يكن قادراً على معرفة ما إذا كان ()get_five ثابت فعلا في وقت التنفيذ. نظرياً هذه الدالة يمكن أن تؤثر على متغير كوني global variable أو استدعاء دوال أخرى غير ثابتة في وقت التنفيذ، إلخ.
قدمت سي++11 الكلمة المفتاحية constexpr والتي تسمح للمستخدم في وقت الترجمة أن يضمن أن الدالة أو مشيد الكائن ثابتاً. المثال السابق يمكن إعادة كتابته كالتالي:
constexpr int get_five() {return 5;}

int some_value[get_five() + 7]; // إنشاء مصفوفة من 12 عنصر، مقبول في السي++11
هذا يسمح للمترجم من الفهم والتأكد من أن ()get_five ثابتة وقت الترجمة.
استخدام constexpr مع الدالة يفرض بعض القيود على ما يمكن للدلة أن تفعله. أولا يجب أن يكون نوع البيانات المرجع من الدالة غير فارغ void. ثانيا داخل جسم الدالة لا يمكن الإعلان عن متغيرات أو تعريف أنواع بيانات جديدة. ثالثا جسم الدالة يمكن فقط أن يحتوي على إعلانات أو جمل فارغة null وجملة إرجاع واحدة. يجب أن يتواجد قيم معطيات بحيث أنه بعد ابدال المعطيات فإن التعبير في جملة الإرجاع ينتج تعبير ثابت.
قبل سي++11 كان يمكن استخدام قيم المتغيرات في التعبيرات الثابتة فقط إذا كانت المتغيرات معلن عن أنها ثابتة بـconst وتم تهيئتها بتعبير ثابت ونوعها أرقم صحيحة أو قائمة عددية. في سي++11 تم حذف القيد المتعلق بأن يكون نوع المتغيرات أرقام صحيحة أو قائمة عددية إذا تم تعريفها باستخدام الكلمة المفتاحية constexpr:
constexpr double earth_gravitational_acceleration = 9.8;
constexpr double moon_gravitational_acceleration = earth_gravitational_acceleration / 6.0;
هذه المتغيرات ثابتة ضمنياً const ويجب أن تهيأ بتعبير ثابت.
لإنشاء قيم بيانات تعبير ثابت من أنواع بيانات معرفة من قبل المستخدم فإن المشيدات يمكن أيضا الإعلان عنها بـconstexpr. جسم دالة مشيد المعلن عنه كتعبير ثابت يمكن أن يحتوى على إعلانات وجمل فارغة فقط، ولا يمكن الإعلان عن متغيرات أو تعرف أنواع بيانات كما هو الحال مع الدوال المعلن عنها بـconstexpr. يجب أن تتواجد قيم معطيات بحيث أنه بعد ابدال المعطيات فإن تهيئة عناصر الصنف سينتج تعبيرات ثابتة. المهدمات لهذه الأنواع يجب أن تكون بسيطة.
عادة يجب تعريف مشيد النسخ لصنف لديه مشيدات تعبيرات ثابتة بأن يكون هو أيضا تعبير ثابت، وذلك للسماح للكائنات من هذا صنف أن يتم إرجاعها بالقيمة من دالة تعبير ثابت. يمكن الإعلان عن أي دالة عضو في الصنف مثل مشيدات النسخ والتحميلات الزائدة للمعاملات وغيرهم كتعبير ثابت طالما أنها مستوفية لشروط الدوال ثابتة التعبير. وهذا يسمح للمترجم أن ينسخ الكائنات في وقت الترجمة ويؤدي العمليات عليهم، إلخ.
إذا تم استدعاء دالة أو مشيد تعبير ثابت بمعطيات غير ثابتة التعبير، فإن الاستدعاء يتصرف كما لو أن الدالة ليست تعبير ثابت، وقيمة النتيجة لا تكون تعبير ثابت كذلك. بالمثل إذا كان تقييم التعبير في جملة الإرجاع لدالة تعبير ثابت لا ينتج تعبيراً ثابتاً فإن النتيجة لن تكون تعبير ثابت.