>an**************@gmail.com wrote:
>I need to write a macro which would have a lot many conditional
#ifdef ... #endif blocks in it.
In article <s_******************************@comcast.com>
Eric Sosman <es*****@acm-dot-org.invalidwrote:
You are out of luck. Even if a macro expansion produces
something that resembles a preprocessor directive, it is not
a preprocessor directive.
Indeed, this is one of the few clear-and-obvious statements in the
C standards. I might even bet that C1x will deliberately screw this
up, just to make things confusing. :-)
>#define _xx_macro (x) {
... \
... \ /* some code (); */
#ifdef _SOME_STMT \
... \
... \
#endif \
... \
... \
}
You need to "turn it inside out:" write several different
definitions of the macro, and use #ifdef (and #ifndef and #if)
to choose which definition is used:
#ifdef SOME_STMT
#define xx_macro ... SOME code ...
#elif defined THAT_STMT
#define xx_macro ... THAT code ...
#else
#define xx_macro ... ELSE code ...
#endif
There is another alternative: give just the "#ifdef"ed sections
their own names. For instance, suppose you want BIG_MACRO to
expand as if it were:
do {
some code here;
#ifdef FOO
code to do foo;
#endif
more code here;
#ifdef BAR
code to do bar;
#else
code to do non-bar;
#endif
final code here;
} while (0)
Now:
#define BIG_MACRO \
do { \
some code here; \
#ifdef FOO \
code to do foo; \
#endif \
...
is no good, because -- as Eric Sosman noted -- even if you manage
to put a preprocessor directive into a "#define", it will not be
examined again later. But suppose, instead, we define two auxiliary
"little macros":
#ifdef FOO
# define LITTLE_FOO_MACRO code to do foo
#else
# define LITTLE_FOO_MACRO /* nothing */
#endif
#ifdef BAR
# define LITTLE_BAR_MACRO code to do bar
#else
# define LITTLE_BAR_MACRO code to do non-bar
#endif
#define BIG_MACRO \
do { \
some code here; \
LITTLE_FOO_MACRO; \
more code here; \
LITTLE_BAR_MACRO; \
final code here; \
} while (0)
The "big" macro now makes use of a series of "little" macros.
These "little macros" must still be defined at the point of
use, which is different from what Eric describes:
>Note that the tests are made at the point where they appear in
the source code. The xx_macro definition will not be altered
by subsequent changes to SOME_STMT and THAT_STMT; it will still
expand according to the way it was originally defined. (Unless
you #undef and re-#define it, of course.)
Here "BIG_MACRO" literally contains "LITTLE_FOO_MACRO". It is at
the point you *use* the big macro, when LITTLE_FOO_MACRO comes out
of the preprocessor, that the preprocessor notices that LITTLE_FOO_MACRO
is also a "#define", and expands it. So you are free to change
the small macros around, after which you will get a different
expansion from the big macro.
As an aside, avoid using identifiers that start with _.
Some of them are available for your use, but many are reserved
either for the language or for the implementation, so your uses
of _xx_macro and _SOME_STMT run the risk of clashing with other
definitions that you cannot control.
Yes -- unless you are "the implementor". It is easy to tell whether
you are "the implementor": you are this person if and only if you
are writing the C compiler itself.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.