سؤال

كل من التوسع الماكرو وتوليد الكود لديهما إيجابيات وسلبيات. ما هو نهجك المفضل ولماذا؟ متى يجب أن نختار واحدة على الآخر؟ يرجى المشورة بلطف. شكرًا لك!

يمكن أن يكون توسع الماكرو مفيدًا للغاية ومفيدًا:http://dtemplatelib.sourceforge.net/table.htm

ضد

بينما يمنحك توليد الكود الكثير من التعليمات البرمجية اللطيفة:http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

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

المحلول

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

void Foo(..args..){
  x = y;
  if (..some test..){
    Bar(arg1, ...)
  }
  while(..another test..){
    ...
  }
  ...
}

و mucks مع بنية التحكم مثل هذا:

void deFoo(..args..){
  if (mode & 1){x = y;}
  {int svmode = mode; if (deIf(..some test..)){
    deBar(((mode & 1) arg1 : 0), ...)
  } mode = svmode;}
  {int svmode = mode; while(deIf(..another test..)){
    ...
  } mode = svmode;}
  ...
}

الآن ، هناك طريقة جيدة حقًا للقيام بذلك كانت تكتب محللًا لـ C أو أيًا كان اللغة الأساسية ، ثم السير في شجرة الحاجز ، وتوليد الرمز الذي أريده. (عندما فعلت ذلك في Lisp ، كان هذا الجزء سهلاً.)

ولكن من يريد أن يكتب محللًا لـ C ، C ++ ، أو أي شيء آخر؟

لذا ، بدلاً من ذلك ، أكتب وحدات الماكرو حتى أتمكن من كتابة الرمز مثل هذا:

void deFoo(..args..){
  PROTECT(x = y);
  IF(..some test..)
    deBar(PROTECT(arg1), ...)
  END
  WHILE(..another test..)
    ...
  END
  ...
}

ومع ذلك ، عندما أقوم بذلك في C# ، قرر شخص ما في حكمته أن وحدات الماكرو سيئة ، ولا أريد أن أكتب محللًا C# ، لذلك يجب أن أقوم بتوليد الكود باليد. هذا ألم ملكي ، لكنه لا يزال يستحق ذلك مقارنة بالطريقة المعتادة لترميز هذه الأشياء.

نصائح أخرى

بالنسبة لـ C ++ ، أفضل إما القالب metaprogramming أو توليد الكود عبر وحدات الماكرو ، ولكن لا تزال وحدات الماكرو لها استخداماتها.

يمكن تغطية المثال الذي قدمته باستخدام DBTEmplatelib بـ C ++ 0x القوالب المتنوعة, ، مع مزايا إضافية مثل فحص النوع وما إلى ذلك

في C أو C ++ ، من الصعب تصحيح توسيع الماكرو. من ناحية أخرى ، فإن كتابة مولد رمز أسهل في تصحيحه لأنه برنامج منفصل في حد ذاته.

ومع ذلك ، يجب أن تدرك أن هذا مجرد قيود على المعالج المسبق C. على سبيل المثال ، في عائلة Lisp من اللغات ، التوسع الكلي هو توليد الكود ، إنها نفس الشيء بالضبط. لكتابة ماكرو ، تكتب برنامجًا (في LISP) لتحويل إدخال S-expression إلى التعبير S آخر ، والذي يتم تمريره بعد ذلك إلى المترجم.

كلاهما يعاني من مشاكلهم. على عكس وحدات الماكرو ، يمكن لتوليد الكود أن ينتج عن رمز قابل للقراءة وقابل للتصحيح (هل حتى كلمة؟) ، ولكنه أقل مرونة وأصعب تغييره.

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