Hacker News new | ask | show | jobs
by geocar 5950 days ago
No, you can't.

I have the following macro in a program I'm writing right now:

    #define DEF(f)static A f##_n(A x);A f(A x){ \
      return r1m(f##_n,x);}static A f##_n(A x)
Turning this into a function is impossible: functions can't define functions in C.

Here's another one:

    #define DEF(f)static A f##_n(void);A f(void){ \
      static int d=0;static A x=0; \
      if(unlikely(!d))d++,x=f##_n(); return x;} \
      static A f##_n(void)
Ignoring the function composition problem, assume you want to implement the semantics here.

If I type this nonsense out for the 60 (or so) times its used, it is likely I'll make a typo that will be difficult to catch.

If I build the table at run-time (roughly the same amount of code), then I accept a run-time cost for something that will be called very frequently.

If I build a table at compile time and fill it at startup, then my program takes longer to start. Maybe if I put a splash screen up my users will forgive me, but that seems dishonest.

A long time ago, programmers did abuse macros as a kind of poor-compiler's inlining, and your advice is good for that: people shouldn't be doing that, and legacy code where it exists should be fixed.

However macros are great for composition. They can greatly improve the readability of some otherwise repetitive code, and while they can be used for evil, they could also be used to solve problems.

1 comments

That's a good exception to the rule, but you have to admit it's not common.

I don't know the context of that source, so I can't make a proper reply to how to work around that. Is it really necessary to put it in the pre-processor? Does it change that often? Perhaps you can script it before pre-processing and compiling. It depends a lot on the design's context, this is probably a bad guess but the point is more often than not there are ways to avoid or minimize macro-hell scenarios, IMHE.

I suppose it's a matter of taste, and I just look at C-style macros as a means to an end.

I suppose I think the fact it's not more common has to do with this knee-jerk reaction to avoid macros like some kind of plague.

Regarding your other point, I agree: at a certain point hacking up the DSL in perl or lisp is going to give enough greater flexibility that it's going to be worth the additional complexity (to the build system, documentation, programmer-requirements, etc).