Well, anyone knows that we can not invoke preprocessor directives from preprocessor macros definitions,
and as likely it might sound, a metamacro has really nothing to do with this kind of stuff - sorry if I
made anyone of you, even for a second, believe I had found a way to fool Santa Claus
nonexistence -. A metamacro is simply and basically a macro that accepts another macro
as its parameter and invokes that macro within it. It might sound obvious, but there're
still plenty room for cool tricks.

The preprocessor will create all the eWd_Sunday, eWd_Monday, etc, for me.
But, there's more. Let's say now that I want to define a struct with bitfield flags for the days of the
week. I can use the metamacro as follow:

The preprocessor will create all the fSunday, fMonday, etc, flags for me.
But WAIT! There's even MORE - did it sound as TV Shopping? -. Let's say now that I want to
create a TRACE function to, given a day of the week index (e.g. eWd_Sunday),
trace a nice and useful day name (i.e. Sunday), and not the dry literal index.
Once again, I can use the metamacro.

And the preprocessor will expand the eWeekend_Sunday and eWeekend_Saturday
constants for me. In the TCX Unit Conversion Library I made plenty use of this
mechanism. I defined units in a metamacro table that expands several of the concrete
structs, tables, constants, and enums that I need. And when I need to change some unit
or to include a new one, I can do that in one single place. That's it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Comments and Discussions

I found this by searching for (( ENUM STRING TRACE )), being somehow finally determined to get to the bottom of this topic - a significant labor-saver for debugging, really it's "ToString() for C-language".I wonder if you managed to mail e.g. Kernighan, Ritchie might they acknowledge oh yes we forgot to put that in the fine manual, I have never seen this before.

It never even occured to me that metamacros might even be possible. Overusing this would probably lead to insanely unreadable code, but this solves a lot of problems I've had in creating maintainable bulletproof interfaces to other developers.

I've been using this technique for a long time.It's especially useful for generating tables ofinformation from external sources and incorporatingthem into your code as switch statements etc.

You can extend the technique to multi-column tablesand tree structures:

#define LIST_FOO(_op_) \_op_(a,b,c) \_op_(d,e,f)

You can pick and choose which columns to expand byusing different _op_ macros.

Tree structures involve setting up a common namingscheme for the subtables and doing some gnarly tokenpasting to recursively expand the subtables... usefulfor describing register sets and enumerated fieldvalues.