C-preprocessor macro question

C

Charlie Zender

Hi,

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

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)

Any help in understanding the cause of this error and how to correct
it to achieve the desired functionality would be appreciated!

Thanks,
Charlie
 
A

Arthur J. O'Dwyer

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:
(e-mail address removed)
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
 
D

Derk Gwen

# Hi,
#
# 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).

As a macro processor, CPP is fatally crippled. In particular you cannot
assume it will permit an #if or #ifdef within a #define. I would suggest
using a widely available real macro processor, perhaps m4, or to use a
scripting language like perl or Tcl as if a macro processor.
 
R

Richard Bos

Derk Gwen said:
# 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).

As a macro processor, CPP is fatally crippled.

As a C preprocessor, though, the C preprocessor is, if anything,
dangerously overpowered and therefore prone to abuse. As a second-tier
programming language to munge the outcome of your main programming
language it lacks ****-around-ability power, true, but that's probably
just as well.
In particular you cannot assume it will permit an #if or #ifdef
within a #define.

Actually, you can (indeed, must) assume that it will _not_ permit
complete preprocessing commands within the expansion of a preprocessor
macro.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top