أضاف C الكلمة الأساسية المضمنة التي يمكن أن تسبق تعريف الوظيفة، مثل:
inline int max_int( int a, int b ) { return a > b ? a : b; }
لإعطاء المترجم "تلميحًا" إلى أن البرنامج بشكل عام قد يستفيد في الأداء من الوظيفة المضمنة .
الوظيفة التي تم تضمينها تم توسيع الكود الخاص بها في كل نقطة يتم استدعاؤها بدلاً من تنفيذ آلية استدعاء الوظيفة العادية لـ:
بالنسبة للوظائف الصغيرة جدًا، يمكن أن يؤدي التضمين إلى تحسين الأداء. ولكن مثل معظم الأشياء الأخرى، هناك مقايضات.
تمت إعادة الكلمة الرئيسية المضمنة إلى C99، ولكن مع متطلبات مختلفة قليلاً - المزيد لاحقًا.
تشبه الوظائف المضمنة (ويقصد بها استبدال العديد من استخدامات) وحدات الماكرو الشبيهة بالوظيفة. بشكل عام، يعد هذا أمرًا جيدًا لأن الوظائف المضمنة هي وظائف ولها دلالات وظيفية كاملة بدلاً من مجرد استبدال النص الذي يقوم به المعالج المسبق الذي لا يفهم لغة C أو C .
ماكرو مكافئ بشكل ساذج للدالة max_int():
#define MAX_INT(A,B) A > B ? A : B /* bad implementation */
يعاني من المشاكل التالية:
بالإضافة إلى ذلك، ماكرو:
لا تحتوي الوظائف المضمنة على أي من هذه المشكلات ومع ذلك يمكنها تحقيق نفس فائدة الأداء. ومن ثم، استخدم الدوال المضمنة بدلاً من وحدات الماكرو الشبيهة بالوظيفة.
كما ذكرنا، التحديد المضمّن هو فقط "تلميح" للمترجم بأن البرنامج بشكل عام قد يستفيد من الأداء من الوظيفة المضمنة. المترجم حر في تجاهل التلميح.
لماذا؟ لأن هناك حالات لا تكون فيها فكرة جيدة أو مستحيلة. تكون الدالة إما غير مضمنة أو غير مضمنة عادةً عندما يكون أي مما يلي صحيحًا:
قد تكون هناك أسباب أخرى. يعتمد الأمر كله بشكل كبير على الوظيفة ووسائطها والمترجم وأي خيارات متاحة لها.
إذا لم يتمكن المترجم من تضمين وظيفة ما أو اختار عدم تضمينها، فإنه لا يحذرك من أنه لم يفعل ذلك (افتراضيًا). بعض المترجمين، على سبيل المثال، gcc، لديهم خيار -Winline الذي سيحذرك ويعطيك سبب عدم تضمين الوظيفة.
يشبه التحديد المضمّن التعليمات البرمجية القديمة التي تحدد التسجيل - وكلاهما مجرد تلميحات.
بالنسبة لمعظم الوظائف، فإن الجزء الأكبر من تكلفة تنفيذ الوظيفة يقع في نص الوظيفة، وليس في آلية استدعاء الوظيفة. ومن ثم، لكي تكون الدالة مرشحة جيدة للتضمين، يجب عمومًا أن تكون:
عندما تكون في شك، قم بتعريف الرمز الخاص بك. الاستخدام المضمن هو ليس كلمة رئيسية سحرية "تجعلني أسرع". بالإضافة إلى ذلك، يمكن أن يؤدي الإفراط في استخدام المضمنة إلى تضخم التعليمات البرمجية مما يجعل أداء برنامجك أسوأ بشكل عام.
للمزيد راجع المرض المضمن.
الوظائف التي غالبًا ما تكون مرشحة جيدة للتضمين تشمل:
وظيفة مضمّنة مثالية تعمل على زيادة الأداء و تقلل من حجم الكود.
ومع ذلك، هناك تحذير واحد لأي دالة مضمنة وهو أنه إذا تغير تعريفها، فسوف يتطلب الأمر إعادة ترجمة كافة التعليمات البرمجية التي تستخدمها.التحسينات المضمنة
تعريفها (وليس فقط إعلانها) في كل ملف .c أو .cpp يتم استخدامه فيه تمامًا مثل الماكرو. ومن ثم، يجب أن تكون الدالة المضمنة محددة في ملف رأس. عادة، يجب أن تحتوي الوظيفة، مثل أي شيء آخر، على تعريف واحد فقط
من خلال الالتزام بقاعدة التعريف الواحدة (ODR). ومع ذلك، نظرًا لأن تعريف الدالة المضمنة "يُرى" في ملفات .c أو .cpp متعددة، يتم تعليق ODR لهذه الوظيفة.من الممكن أن يكون لديك تعريفات مختلفة للوظائف المضمنة التي لها نفس الاسم، ولكن هذا يؤدي إلى سلوك غير محدد لأن المترجم ليس لديه طريقة للتحقق من أن كل تعريف هو نفسه.
لتضمين دالة في لغة C، كل ما عليك فعله هو بادئة تعريف الدالة بكلمة مضمنة - هذا كل شيء. سيقوم المترجم و/أو الرابط تلقائيًا بتجاهل كافة التعريفات باستثناء تعريف واحد من الملف القابل للتنفيذ النهائي لك.ومع ذلك، لتضمين دالة في لغة C، يجب عليك بالإضافة إلى ذلك
أن تخبر المترجم صراحةً في ملف .o لوضع التعريف الوحيد في حالة كون المترجم إما غير قادر أو غير راغب في تضمين دالة عبر مضمنة خارجية.
على سبيل المثال، في ملف .c واحد فقط، يمكنك الإعلان عن وظيفة مثل:
//util.c
المضمنة الخارجية int max_int( int, int );
هذا يخبر المترجم "بوضع التعريف الوحيد لـ max_int() في util.o."
// util.c extern inline int max_int( int, int );
ثابت مضمن int max_int( int a, int b ) { العودة أ> ب؟ أ : ب؛ }
إذا قمت بذلك، فعندئذ:
static inline int max_int( int a, int b ) { return a > b ? a : b; }لا يتعين عليك الإعلان عن وظيفة خارجية مضمنة في أي مكان.
مراجع
أسلوب ترميز نواة لينكس، §15 المرض المضمن.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3