views:

502

answers:

4

Both Macro expansion & Code generation have pros & cons. What's your favorite approach and why? When should we choose one over the other? Please kindly advise. Thank you!

Macro expansion can be very handy & helpful: http://dtemplatelib.sourceforge.net/table.htm

vs

While Code generation gives you plenty of nice code: http://code.google.com/p/protobuf/ http://incubator.apache.org/thrift/

+4  A: 

In C or C++, macro expansion is notoriously difficult to debug. On the other hand, writing a code generator is easier to debug because it's a separate program in itself.

However, you should be aware that this is merely a limitation of the C preprocessor. For example, in the Lisp family of languages, macro expansion is code generation, they're exactly the same thing. To write a macro, you write a program (in Lisp) to transform S-expression input into another S-expression, which is then passed to the compiler.

Greg Hewgill
Thanks for your reply, Greg. It takes more time to write a decent code generator and macros look like a quick hack to get things done.
Viet
++ My sentiments exactly. It would be nice if there were a way to step through the preprocessing. Even so, I prefer macros if the code generation is simple enough.
Mike Dunlavey
+7  A: 

For c++ I prefer either template metaprogramming or code generation over macros, but macros still have their uses.

The example you have given with dbtemplatelib could be covered with c++0x Variadic Templates, with additional benefits like type checking etc.

drhirsch
Thanks for your suggestion. Templates have their virtues too. Variadic macros are there but variadic templates are yet to be popular as C++0x is still new.
Viet
Well, to be exact, it isn't even out yet, and it will rather be a "c++1x". But variadic templates are implemented in some compilers, for example, to use them with gcc, you have to add "-std=c++0x" as a compiler switch.
drhirsch
+1  A: 

It's a tradeoff. Let me give an example. I stumbled on the technique of differential execution around 1985, and I think it's a really good tool for programming user interfaces. Basically, it takes simple structured programs like this:

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

and mucks with the control structure like this:

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;}
  ...
}

Now, a really good way to do that would have been to write a parser for C or whatever the base language is, and then walk the parse tree, generating the code I want. (When I did it in Lisp, that part was easy.)

But who wants to write a parser for C, C++, or whatever?

So, instead, I just write macros so that I can write the code like this:

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

However, when I do this in C#, somebody in their wisdom decided macros were bad, and I don't want to write a C# parser, so I gotta do the code generation by hand. This is a royal pain, but it's still worth it compared to the usual way of coding these things.

Mike Dunlavey
+1 thanks Mike. That's the best answer :)
Viet
+3  A: 

Both have their problems. Unlike macros, code generation can produce readable and debuggable (is that even a word?) code, but it is less flexible and harder to change.

Nemanja Trifunovic
+1. thanks for reply.
Viet