Расширение макроса C / C++ против генерации кода

как расширение макроса, так и генерация кода имеют плюсы и минусы. Какой ваш любимый подход и почему? Когда мы должны предпочесть одно другому? Пожалуйста, пожалуйста, посоветуйте. Спасибо!

расширение макроса может быть очень удобно и полезно: http://dtemplatelib.sourceforge.net/table.htm

vs

в то время как генерация кода дает вам много хорошего код: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

4 ответов


- это компромисс. Позвольте привести пример. Я наткнулся на технику дифференциальные исполнение около 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 или любого базового языка, а затем пройти синтаксический анализ дерево, генерирующее код, который я хочу. (Когда я шепелявил, это было легко.)

но кто хочет написать парсер для C, C++ или что?

поэтому вместо этого я просто пишу макросы, чтобы написать код следующим образом:

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

однако, когда я делаю это на C#, кто-то в своей мудрости решил, что макросы были плохими, и я не хочу писать парсер C#, поэтому я должен делать генерацию кода вручную. Это королевская боль, но она того стоит по сравнению с обычный способ кодирования этих вещей.


для c++ я предпочитаю либо метапрограммирование шаблонов, либо генерацию кода над макросами, но макросы все еще используют их.

пример, который вы дали с dbtemplatelib, может быть покрыт c++0x Variadic Шаблоны, С дополнительными преимуществами, как проверка типов и т. д.


В C или C++, макроподстановка, как известно, трудно отлаживать. С другой стороны, писать генератор код легче отлаживать, потому что это отдельная программа сама по себе.

однако вы должны знать, что это всего лишь ограничение препроцессора C. Например, в семействе языков Lisp расширение макросов is генерация кода, это точно то же самое. Чтобы написать макрос, вы пишете программу (в Lisp) для преобразования ввода s-выражения в другое s-выражение, которое затем передается компилятору.


У обоих есть свои проблемы. В отличие от макросов, генерация кода может производить чтения и отладки (есть такое слово?) код, но он менее гибкий и его сложнее изменить.