Macromancy, Part 2

The Challenge

Given a macro that expands to an arbitrary list of headers, include every header in the list, in order.

#define HEADERS "stdio.h", "stdlib.h", "assert.h"
#include "include_dynamic.h"
// stdio.h, stdlib.h, and assert.h are now included and available.

Progress So Far

The C preprocessor is a powerful tool, but not a particularly versatile one. Rather, it does a few specific things, and people have taken advantage of its workings to compose those capabilities to accomplish their tasks. And sometimes, to do something ridiculous and overengineered…like this.


In section 6.10.2, paragraph 8 of the C11 standard, this example is specifically called out as legal (if implementation-defined):

#if VERSION == 1
  #define INCFILE "vers1.h"
#elif VERSION == 2
  #define INCFILE "vers2.h" // and so on
  #define INCFILE "versN.h"
#include INCFILE

Yikes! Do people really want to do this? If I encountered this in a real program, I’d try to get rid of it—in most cases I figure you can just put the #includes inside the #if and be done with it. You can’t even do any clever tricks like building up a path, at least not portably.

So of course, after telling someone else about this, my next reaction was how to take it further. (Please do not put this in a real program.)