c++ - وظائف مضمنة مقابل ماكرو Preprocessor




macros inline (12)

من منظور الترميز ، فإن وظيفة مضمنة تشبه وظيفة. وبالتالي ، فإن الاختلافات بين وظيفة مضمنة وماكرو هي نفسها الاختلافات بين وظيفة وماكرو.

من منظور ترجمة ، تشبه دالة مضمنة الماكرو. يتم حقنه مباشرة في الشفرة ، لا يسمى.

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

كيف تختلف وظيفة مضمنة عن ماكرو preprocessor؟


تتجاهل وحدات الماكرو مساحات الأسماء. وهذا يجعلهم أشرار.


سوف تتصرف الدالات المضمّنة كمكالمة دالة إذا كان هناك أي عبارة تكرارية أو متكررة في ذلك ، وذلك لمنع تكرار تنفيذ التعليمات. من المفيد جدا لحفظ الذاكرة الشاملة للبرنامج الخاص بك.


تعد وحدات الماكرو preprocessor مجرد أنماط بديلة يتم تطبيقها على التعليمات البرمجية. يمكن استخدامها في أي مكان تقريبًا في شفرتك نظرًا لاستبدالها بتوسعاتها قبل بدء أي عملية ترجمة.

الدالات المضمنة هي وظائف فعلية يتم حقن جسمها مباشرة في موقع الاتصال الخاص بها. لا يمكن استخدامها إلا في حالة إجراء مكالمة دالة.

الآن ، بقدر ما تستخدم وظائف الماكرو مقابل المضمنة في سياق يشبه الوظيفة ، يجب أن يكون نصح:

  • لا تكون وحدات الماكرو آمنة ، ويمكن توسيعها بغض النظر عما إذا كانت صحيحة بشكل نسبي - ستقوم مرحلة الترجمة بإبلاغ الأخطاء الناتجة عن مشكلات توسيع الماكرو.
  • يمكن استخدام وحدات الماكرو في السياق الذي لا تتوقعه ، مما يؤدي إلى حدوث مشكلات
  • تكون وحدات الماكرو أكثر مرونة ، حيث يمكنها توسيع وحدات الماكرو الأخرى - بينما لا تقوم الوظائف المضمنة بذلك بالضرورة.
  • يمكن أن تؤدي وحدات الماكرو إلى تأثيرات جانبية بسبب توسعها ، نظرًا لأن تعبيرات الإدخال يتم نسخها أينما ظهرت في النموذج.
  • لا يتم دائمًا ضمان تضمين الدالة المضمنة - حيث يقوم بعض المترجمين بذلك فقط في إصدارات الإصدار ، أو عند تهيئتهم بشكل خاص للقيام بذلك. أيضا ، في بعض الحالات قد لا يكون ممكنا.
  • يمكن أن توفر الدالات المضمّنة نطاقًا للمتغيرات (خاصةً الثابتة منها) ، ويمكن أن تقوم وحدات الماكرو preprocessor فقط بهذا في كتل التعليمات البرمجية {...} ، ولن تتصرف المتغيرات الثابتة بالطريقة نفسها تمامًا.

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

Here عدة نقاط أقل وضوحًا.


ستحافظ الدالة المضمنة على دلالات القيمة ، بينما يقوم ماكرو preprocessor بنسخ بناء الجملة. يمكنك الحصول على أخطاء دقيقة للغاية مع ماكرو preprocessor إذا كنت تستخدم الوسيطة عدة مرات - على سبيل المثال إذا كانت الحجة تحتوي على تحور مثل "i ++" بعد أن تنفيذ مرتين هو مفاجأة. لن تحتوي الدالة المضمنة على هذه المشكلة.


أولاً ، وحدات الماكرو preprocessor هي فقط "نسخ لصق" في التعليمات البرمجية قبل التحويل البرمجي. لذلك لا يوجد فحص من نوع ، ويمكن أن تظهر بعض الآثار الجانبية

على سبيل المثال ، إذا كنت ترغب في مقارنة قيمتين:

#define max(a,b) ((a<b)?b:a)

تظهر التأثيرات الجانبية إذا استخدمت max(a++,b++) على سبيل المثال (ستزداد a أو b مرتين). بدلا من ذلك ، استخدم (على سبيل المثال)

inline int max( int a, int b) { return ((a<b)?b:a); }

في دول مجلس التعاون الخليجي (لست متأكداً من الآخرين) ، معلنة دالة مضمنة ، هو مجرد تلميح إلى المترجم. ولا يزال مترجمًا في نهاية اليوم ليقرر ما إذا كان يشتمل على جسم الوظيفة عندما يتم استدعائها.

الفرق بين الدالات المضمنة ووحدات الماكرو preprocessor كبير نسبيًا. وحدات الماكرو preprocessor هي فقط استبدال النص في نهاية اليوم. أنت تتخلى عن الكثير من قدرة المحول البرمجي على التحقق من نوع التحقق من الوسيطات ونوع الإرجاع. يختلف تقييم الحجج بشكل كبير (إذا كانت للتعبيرات التي تمررها إلى الوظائف تأثيرات جانبية ، سيكون لديك تصحيح وقت ممتع جدًا). هناك اختلافات دقيقة حول حيث يمكن استخدام وظائف ووحدات الماكرو. على سبيل المثال ، إذا كان لدي:

#define MACRO_FUNC(X) ...

حيث يعرف MACRO_FUNC بوضوح جسم الدالة. يجب توخي العناية الخاصة بحيث تعمل بشكل صحيح في جميع الحالات يمكن استخدام وظيفة ، على سبيل المثال MACRO_FUNC سيئة مكتوبة قد يسبب خطأ في

if(MACRO_FUNC(y)) {
 ...body
}

يمكن استخدام وظيفة عادية بدون أي مشكلة هناك.


تتشابه الدالات المضمنة مع وحدات الماكرو (لأنه يتم توسيع رمز الدالة عند نقطة الاستدعاء في وقت التحويل البرمجي) ، يتم تحليل الدالات المضمنة بواسطة المحول البرمجي ، بينما يتم توسيع وحدات الماكرو بواسطة المعالج الأولي. نتيجة لذلك ، هناك العديد من الاختلافات الهامة:

  • تتبع الوظائف المضمنة جميع بروتوكولات سلامة الأنواع المطبقة على الوظائف العادية.
  • يتم تحديد الدالات المضمنة باستخدام نفس البنية مثل أي دالة أخرى باستثناء أنها تتضمن الكلمة الأساسية المضمنة في تعريف الدالة.
  • يتم تقييم التعبيرات التي تم تمريرها كوسيطة للوظائف المضمنة مرة واحدة.
  • في بعض الحالات ، يتم تمرير التعبيرات حيث يمكن تقييم الوسيطات إلى وحدات الماكرو أكثر من مرة. http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx

  • يتم توسيع وحدات الماكرو في وقت ما قبل التحويل البرمجي ، لا يمكنك استخدامها للتصحيح ، ولكن يمكنك استخدام وظائف مضمنة.

- مقالة جيدة : http://www.codeguru.com/forum/showpost.php؟p=1093923&postcount=1

.


لإضافة فرق آخر إلى تلك المعطاة بالفعل: لا يمكنك #define خلال #define في المصحح ، ولكن يمكنك التنقل خلال وظيفة مضمنة.


#include<iostream>
using namespace std;
#define NUMBER 10 //macros are preprocessed while functions are not.
int number()
{ 
    return 10;
}
/*In macros, no type checking(incompatible operand, etc.) is done and thus use of micros can lead to errors/side-effects in some cases. 
However, this is not the case with functions.
Also, macros do not check for compilation error (if any). Consider:- */
#define CUBE(b) b*b*b
int cube(int a)
{
 return a*a*a;
}
int main()
{
 cout<<NUMBER<<endl<<number()<<endl;
 cout<<CUBE(1+3); //Unexpected output 10
 cout<<endl<<cube(1+3);// As expected 64
 return 0;
}

تكون وحدات الماكرو أسرع من الدالات لأنها لا تتضمن الحمل الفعلي لاستدعاء الدالة.

بعض عيوب وحدات الماكرو: لا يوجد نوع تدقيق. من الصعب تصحيح لأنها تسبب استبدال بسيط.ماكرو ليس مساحة الاسم ، لذلك يمكن أن يؤثر ماكرو في مقطع واحد من التعليمات البرمجية على مقطع آخر. يمكن أن تتسبب وحدات الماكرو في حدوث تأثيرات جانبية كما هو موضح في مثال CUBE () أعلاه.

وحدات الماكرو عادة ما تكون بطانة واحدة. ومع ذلك ، يمكن أن تتكون من أكثر من سطر واحد. لا توجد مثل هذه القيود في وظائف.


لا يمكن أبداً أن يكون المرجع NULL .





c++ c macros inline