Click here to Skip to main content
13,351,239 members (48,332 online)
Click here to Skip to main content
Add your own
alternative version


17 bookmarked
Posted 1 Dec 1999

Cool Techniques - Metamacros

, 1 Dec 1999
Rate this:
Please Sign up or sign in to vote.
A technique to allow macros to call other macros
<!-- Article Starts -->

A cool technique I used in my TCX Unit Conversion Library is what I call "metamacros".

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.

For example, the following is a metamacro for the days of the week.

#define _WEEKDAYS_METADEFS( _m )\
   _m( Sunday )\
   _m( Monday )\
   _m( Tuesday )\
   _m( Wednesday )\
   _m( Thursday )\
   _m( Friday )\
   _m( Saturday )

Now, lets use this metamacro to expand an enum with indexes for the days of the week. All I have to do is:

#define _ENUM_WEEKDAY( Name ) eWd_##Name,


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:

#define _BITFIELD_WEEKDAY( Name )   bool f##Name: 1;


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.

#define _STR_WEEKDAY( Name ) ##Name,

void TraceWeekDayName( int i )
   static const LPCTSTR _aWdNames[ ] =

   if( i < 0 || i < sizeof(_aWdNames)/sizeof(_aWdNames[0]) )
      TRACE( "Invalid" );
      TRACE( _aWdNames[i] );

Do note that, if I have to change the definition of the days of the week, I don't have to make the follow up to every other construction that might be affected by it: the preprocessor does it for me.

Another trick is that I can give the metamacro only the macros prefix, or "macros namespace" (ugh!). Let's show an example, still with the days of the week.

#define _WEEKDAYS_METADEFS( _m )\
   _m##_WEEKEND( Sunday )\
   _m ( Monday )\
   _m( Tuesday )\
   _m( Wednesday )\
   _m( Thursday )\
   _m( Friday )\
   _m##_WEEKEND ( Saturday )

Now, to expand the same enum for the days of the week I did before, I must do that:

#define _ENUM_WEEKDAY( Name )          eWd_##Name,
#define _ENUM_WEEKDAY_WEEKEND( Name )  eWd_##Name,


But, if I want to expand an enum only for the days of the week that are part of the weekend, I can do this:

#define _ENUM_WEEKDAY2( Name )
#define _ENUM_WEEKDAY2_WEEKEND( Name )   eWeekend_##Name,


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.


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.

A list of licenses authors might use can be found here


About the Author

Thales P. Carvalho
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralActually it's #define _STR_WEEKDAY( Name ) # Name, Pin
pg--az16-May-07 12:57
memberpg--az16-May-07 12:57 
GeneralSmall bug Pin
Ingo K. hunsinger11-Apr-00 2:39
sussIngo K. hunsinger11-Apr-00 2:39 
GeneralRe: Small bug Pin
John Bates11-Feb-02 16:23
memberJohn Bates11-Feb-02 16:23 
GeneralNeat Pin
Rob Deary20-Mar-00 9:43
sussRob Deary20-Mar-00 9:43 
GeneralRe: Neat Pin
Anonymous14-Jun-02 16:04
memberAnonymous14-Jun-02 16:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180111.1 | Last Updated 2 Dec 1999
Article Copyright 1999 by Thales P. Carvalho
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid