Question

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/

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top