469,613 Members | 1,324 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,613 developers. It's quick & easy.

#ifdef within a #define

Hi,

I need to write a macro which would have a lot many conditional
#ifdef ... #endif blocks in it.
#define _xx_macro (x) {
... \
... \ /* some code (); */
#ifdef _SOME_STMT \
... \
... \
#endif \
... \
... \
}

Is such a thing possible, or I need to make the #ifdefs out side the
#define, and for each #ifdef .. #else ... #endif, I should write a
different #define? I am using XLC compiler. Is this compiler
dependent?

Thanks
Anirbid

Feb 17 '07 #1
6 26046
an**************@gmail.com wrote:
Hi,

I need to write a macro which would have a lot many conditional
#ifdef ... #endif blocks in it.
You are out of luck. Even if a macro expansion produces
something that resembles a preprocessor directive, it is not
a preprocessor directive.
#define _xx_macro (x) {
... \
... \ /* some code (); */
#ifdef _SOME_STMT \
... \
... \
#endif \
... \
... \
}

Is such a thing possible, or I need to make the #ifdefs out side the
#define, and for each #ifdef .. #else ... #endif, I should write a
different #define? I am using XLC compiler. Is this compiler
dependent?
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

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.)

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.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 17 '07 #2
On Feb 17, 5:46 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
anirbid.baner...@gmail.com wrote:
Hi,
I need to write a macro which would have a lot many conditional
#ifdef ... #endif blocks in it.
#define _xx_macro (x) {
... \
... \ /* some code (); */
#ifdef _SOME_STMT \
... \
... \
#endif \
... \
... \
}
Is such a thing possible, or I need to make the #ifdefs out side the
#define, and for each #ifdef .. #else ... #endif, I should write a
different #define? I am using XLC compiler. Is this compiler
dependent?
The other possibility would be to turn this into a real function:

#define _xx_macro (x) real_function(x);

void real_function(int x) /* or whatever type */
{
...
... /* some code (); */
#ifdef _SOME_STMT
...
...
#endif
...
...
}

The benefits of using actual functions instead of macros can be
enormous in terms of code clarity and maintainability, so unless you
absolutely need it to be a macro, I'd suggest something like this.

Michael

Feb 17 '07 #3
Michael wrote:
On Feb 17, 5:46 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
>anirbid.baner...@gmail.com wrote:
>>Hi,
I need to write a macro which would have a lot many conditional
#ifdef ... #endif blocks in it.
#define _xx_macro (x) {
... \
... \ /* some code (); */
#ifdef _SOME_STMT \
... \
... \
#endif \
... \
... \
}
Is such a thing possible, or I need to make the #ifdefs out side the
#define, and for each #ifdef .. #else ... #endif, I should write a
different #define? I am using XLC compiler. Is this compiler
dependent?

The other possibility would be to turn this into a real function:
[...]
Note that the O.P.'s example is not a function-like macro.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 18 '07 #4
>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.
Feb 18 '07 #5
Chris Torek <no****@torek.netwrites:
[...]
> 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.
*Or* the standard C library (i.e., the library code that implements
the standard headers defined in the standard).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 18 '07 #6
# >>I need to write a macro which would have a lot many conditional
# >>#ifdef ... #endif blocks in it.
# >>#define _xx_macro (x) {
# >> ... \
# >> ... \ /* some code (); */
# >>#ifdef _SOME_STMT \
# >> ... \
# >> ... \
# >> #endif \
# >> ... \
# >> ... \
# >>}
# >>Is such a thing possible, or I need to make the #ifdefs out side the
# >>#define, and for each #ifdef .. #else ... #endif, I should write a
# >>different #define? I am using XLC compiler. Is this compiler
# >>dependent?

You can sometimes simulate with an include file.

So you have something
macro.define:
#ifndef x
#error parameter 'x' is not defined.
#endif
/* some code (); */
#ifdef _SOME_STMT
...
...
#endif
...
...
#undef x
somecode.c
...
#define x ABC
#include "macro.define"
...
#define x PQR
#include "macro.define"
...
#define x (X+Y+Z)
#include "macro.define"
...

Or else use a real macro processor.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Quit killing people. That's high profile.
Feb 19 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by kUfa.scoopex | last post: by
15 posts views Thread by Jorge Naxus | last post: by
2 posts views Thread by Whywhat | last post: by
7 posts views Thread by Kenneth Brody | last post: by
7 posts views Thread by Nobody | last post: by
1 post views Thread by Michael Sgier | last post: by
6 posts views Thread by canoewhiteh2o | last post: by
10 posts views Thread by Yevgen Muntyan | last post: by
reply views Thread by devrayhaan | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.