
Not a bug. Empty macro arguments are currently undefined behavior in C++. There is nothing that I can do about that. C99 added explicit support for them, but they are not (yet) part of C++.
I very much appreciate your answer. And ultimately this hasn't become a big deal, since - as you saw - I found a way around the problem all the same. But now let me answer a very good question you asked:
#define ENUM(name, start, entries)\ BOOST_PP_SEQ_ENUM( \ BOOST_PP_IIF(ENUMS, \ (typedef enum{ BOOST_PP_SEQ_HEAD(entries) = start) \ BOOST_PP_SEQ_TAIL(entries) \ (LAST_##name } name;) \ , \ (static void PP_NILFUNC();) \ ) \ )
Why are you doing the test *inside* of the invocation of SEQ_ENUM?
The short answer: I wanted a **single** ENUM macro definition that permitted the printable strings *AND* the enums themselves to be conditionally compileable. I think my intention will make more sense if I show you the entire printable enum. It looks like this: #ifndef ENUMS /*By default, turn enums on*/ #define ENUMS 1 #endif #ifndef ESTRINGS /*By default, turn printable strings on*/ #define ESTRINGS 1 #endif #ifndef EDEBUG #define EDEBUG 0 /*By default, turn ESTRINGS "compliment" condition off */ #endif /*Used internally by the ENUM macro*/ #ifdef ENUM_STR #undef ENUM_STR #endif #define ENUM_STR(r, data, elem) BOOST_PP_STRINGIZE(elem) #define ENUM(name, start, entries) \ BOOST_PP_SEQ_ENUM( \ BOOST_PP_IIF(ENUMS, \ (typedef enum{ BOOST_PP_SEQ_HEAD(entries) = start) \ BOOST_PP_SEQ_TAIL(entries) \ (LAST_##name } name;) \ , \ (static void PP_NILFUNC();) \ ) \ ) \ BOOST_PP_SEQ_ENUM( \ BOOST_PP_IIF(BOOST_PP_BITOR(EDEBUG,ESTRINGS), \ (static const char* name##_Str[]={ BOOST_PP_STRINGIZE(BOOST_PP_SEQ_HEAD(entries)) ) \ BOOST_PP_SEQ_TRANSFORM(ENUM_STR, _, BOOST_PP_SEQ_TAIL(entries) ) \ (};) \ , \ (static void PP_NILFUNC();) \ ) \ ) Now, as I think you pointed out yourself, you can't place the BOOST_PP_SEQ_ENUM inside of a BOOST_PP_EXPR_IIF statement like this: #define ENUM(name, start, entries) \ BOOST_PP_EXPR_IIF(ENUMS)( \ BOOST_PP_SEQ_ENUM( \ (typedef enum { BOOST_PP_SEQ_HEAD(entries) = start) \ BOOST_PP_SEQ_TAIL(entries) \ (LAST_ ## name } name;) \ ) \ ) \ So, what I've shown you in the printable enum above was the only solution I could think of to achieve the result: i.e. a **single** ENUM macro definition that permitted the printable strings *AND* the enums themselves to be conditionally compileable. On the other hand, I'm intrigued with what you presented here: #define ENUM(name, start, entries) \ BOOST_PP_IIF( \ ENUMS, \ BOOST_PP_SEQ_ENUM, BOOST_PP_TUPLE_EAT(1) \ )( \ (typedef enum { BOOST_PP_SEQ_HEAD(entries) = start) \ BOOST_PP_SEQ_TAIL(entries) \ (LAST_ ## name } name;) \ ) \ I didn't pay attention to BOOST_PP_TUPLE_EAT when I was (frantically) trying to make a printable enum. Perhaps it is a means by which I can get rid of the "hack" I described earlier? It sure looks like it will work! Oh, by the way, I was so pleased with the printable enum - I was actually thinking of submitting it for inclusion into Boost. Would a submission like that be more nuisance than benefit? Thanks, -Brent