Is there any way in standard C—or with GNU extensions—to append stuff to a macro definition? E.g., given a macro defined as
#define List foo bar
can I append bas
so that it List
expands as if I’d defined it
#define List foo bar bas
?
I was hoping I could do something like this:
#define List foo bar bas
#define List_ Expand(List)
#undef List
#define List Expand(List_) quux
but I can’t figure out how to define the Expand()
macro so it’ll do what I want.
Motivation: I’m playing with discriminated/tagged unions along these lines:
struct quux_foo { int x; };
struct quux_bar { char *s; };
struct quux_bas { void *p; };
enum quux_type {quux_foo, quux_bar, quux_bas};
struct quux {
enum quux_type type;
union {
struct quux_foo foo;
struct quux_bar bar;
struct quux_bas bas;
} t;
};
I figure this is a good place for the X-macro. If I define a macro
#define quux_table X(foo) X(bar) X(bas)
the enumeration & structure can be defined thus, and never get out of sync:
#define X(t) quux_ ## t,
enum quux_type {quux_table};
#undef X
#define X(t) struct quux_ ## t t;
struct quux {
enum quux_type type;
union {quux_table} t;
};
#undef X
Of course, the quux_*
structures can get out of sync, so I’d like to do something like this, only legally:
struct quux_foo { int x; };
#define quux_table quux_table X(foo)
struct quux_bar { char *s; };
#define quux_table quux_table X(bar)
struct quux_bas { void *p; };
#define quux_table quux_table X(bas)
(Well, what I really want to be able to do is something like
member_struct(quux, foo) { int x; };
but I’m well aware that macros cannot be (re)defined from within macros.)
Anyhow, that’s my motivating example. Is there a way to accomplish this?
Boost.Preprocessor examples are fine, if you can show me how to make the X-macro technique work with that library.
Effectively, no.
Macros are lazily evaluated. When you
#define List_ Expand(List)
, its replacement list is the sequence of four tokensExpand
,(
,List
, and)
. There isn't any way to expand a macro into a replacement list.All macro replacement takes place when a macro is invoked.
I'd recommend looking at using the Boost.Preprocessor library for automatic code generation. It's a bit of work, but you can accomplish some fairly impressive things using it. It should be fully compatible with C.
I'm not sure if this helps, but you can do vari arg macros. Mr. Conrad of the x264 project loves preprocessor abuse. If they sound like they might help you can find out more Here
There is a way!
Using the new _Pragma keyword this can be achieved in gcc (though not with msvc)
If you pop a macro within it's own definition it will delay it's expansion until the macro is expanded for the first time. This allows you to make it's previous expansion part of it's own definition. However, since it is popped during it's expansion, it can only be used once
Here is some sample code to see it in action
This option should make automatic code generation a fair bit easier, though unfortunately only on gcc (maybe clang, haven't tested)
To be honest there is no reason I can find why this must work, it is most probably undefined behavior that happens to work. I'm guessing the reason is that after popping foo, the current macro being expanded is no longer associated with the name foo which allows the symbol
foo
to be expanded, but that is only my conjectureEdit:
After testing on clang, this
does notdoes work on clang.I don't know why I thought clang did not work, maybe it didn't on a different machine. I definitely did get it to work with the code given though