On Tue, 23 Dec 2003, Charlie Zender wrote:
>
> I want to have a CPP macro that tests the value of a token and
> returns the string "No" if the token is undefined (or 0) and
> returns "Yes" if the token is defined (non-zero).
In general I believe this is impossible, but someone may yet
prove me wrong. To what would your hypothetical macro evaluate in
the following "corner cases"?
#define FOO
#define FOO 0
#define FOO 0+0
#define FOO "bar"
#define FOO +
#define FOO if
Should it yield "Yes", "No", some other defined result, or would
it be allowed to crash completely? Or are you just looking for a
macro to yield "Yes" or "No" based on the integer value of a
#defined or un#defined macro -- in that case, I think you might
be looking for something as simple as
#define P(x) x
#define YESNO(foo) (P(foo)+0)? "Yes": "No")
#define foo 42 yields "Yes"
#define foo 0 yields "No"
#define foo yields "No"
but it may not like complicated expressions.
> Then I can have C code that self-diagnoses its configuration with,
> e.g.,
>
> #define TKN2YESNO(x) ((x)==0 ? ("No")
"Yes"))
> (void)fprintf(stderr,"The token FOO is defined: %s",TKN2YESNO(FOO));
> (void)fprintf(stderr,"The token BAR is defined: %s",TKN2YESNO(BAR));
>
> However, my definition of TKN2YESNO() does not work.
> The GCC compiler on Linux flags an when I invoke TKN2YESNO() as above:
>
> nco_scm.c:195: error: `FOO' undeclared (first use in this function)
This Won't Work (TM). If the token 'FOO' is *completely* undefined,
it won't macro-expand to anything, and you'll be left with 'FOO',
which the compiler will then treat like any other identifier -- as
if it were a variable name or something. And you'll get errors.
If this is what you want, you'll have to be a *lot* more specific
about what counts as "defined" and what doesn't, and maybe someone
will be nice enough to whip up a hack like the "month-day-year"
preprocessor hack Martin Dickopp did in this thread:
For example, you might get somewhere useful by stringizing the
thing. Other than that, I think you're stuck with
#if defined(foo) && (foo != 0)
...
#endif
which is tedious.
HTH,
-Arthur