#ifdef vs #if vs #if defined

M

Michael B Allen

Which is the preferred method for preprocessor tests and why?

#ifdef XYZ
or
#if XYZ
or
#if defined(XYZ)

and

#elif
or
#elsif

and

#ifndef XYZ
or
#if !defined(XYZ)

Mike
 
E

Eric Sosman

Michael said:
Which is the preferred method for preprocessor tests and why?

#ifdef XYZ
or
#if XYZ
or
#if defined(XYZ)

The first and third are equivalent; use whichever
you please. The second is slighly different from the
other two, since it will test "false" if XYZ is
defined but with the value zero.
and

#elif
or
#elsif

The first is strongly preferred, except by people
who enjoy reading error messages.
and

#ifndef XYZ
or
#if !defined(XYZ)

Equivalent; use whichever you like.
 
W

Walter Roberson

:Which is the preferred method for preprocessor tests and why?

YMMV, but:

- expression format is the easiest to change later.
- you are likely going to need to use expression format for some of
what you do. It gets to look odd if you deliberately avoid expression
format when possible.

:#ifdef XYZ
:eek:r
:#if XYZ
:eek:r
:#if defined(XYZ)

The second of those does not have the same meaning as the other two.
If XYZ is defined as 0, then #ifdef and #if defined are both true
but the #if XYZ form is false.
 
P

philipx

Michael said:
Which is the preferred method for preprocessor tests and why?
#ifdef XYZ
or
#if XYZ
or
#if defined(XYZ)

"#ifdef XYZ" is different from "#if XYZ", the former is testing the
existence of XYZ while the latter tests the value of XYZ.
IMO, you can freely choose between "#ifdef XYZ" and "#if defined(XYZ)", with
one exception, you cannot test for more than one thing in a single
"#ifdef".
consider the following, it's better to use "#if defined" than "#ifdef":

/* Test for the support of C99 Standard */
#if defined(__STDC_VERSION__) && __STD_VERSION__ > 199901L
/* ...something legal in C99 only */
#elif
/* ...something alternative */
#endif

#elif
or
#elsif

I can't remember I saw something like #elsif, is it a compiler-specific
extension? (okay, I might saw it when I used Turob C 2.0, but that's long
time ago, 10+ years, I am not quite sure).
by the way, #elsif is not a standard c preprocessor feature, avoid using it.
and
#ifndef XYZ
or
#if !defined(XYZ)
Mike
What's true for "#ifdef" and "#if" is also true here.
 
K

Keith Thompson

CBFalconer said:
Minor nit - electron-positron annihilation produces gamma rays, not
electricity nor light.

Minor nit - gamma rays are light. They're just very very very very
very blue.
 
C

Chris Torek

IMO, you can freely choose between "#ifdef XYZ" and "#if defined(XYZ)", with
one exception, you cannot test for more than one thing in a single
"#ifdef".

Right.

Also, as a side note, the parentheses are not required when using
the "defined" pseudo-keyword (it is really just a magic identifier,
rather than a keyword, since keywords do not exist in these phases
of translation):

#ifdef X
#if defined(X)
#if defined X

are all synonymous.
consider the following, it's better to use "#if defined" than "#ifdef":

/* Test for the support of C99 Standard */
#if defined(__STDC_VERSION__) && __STD_VERSION__ > 199901L
/* ...something legal in C99 only */

This test is a little odd, because if __STDC_VERSION__ is not
defined, the test:

#if __STDC_VERSION__ > 199901L

is entirely legal and "means" the same thing as:

#if 0 > 199901L

which is of course false. In preprocessor expressions, undefined
identifiers *must* be replaced with 0. This is why:

#if sizeof(int) == 4

*must* produce a diagnostic, because -- assuming you have not done
something silly like "#define sizeof" -- it is syntactically the
same as:

#if 0(0) == 4

Once the required diagnostic has been emitted, a C compiler can go
back and "notice" that "sizeof" is not only not-defined but will
also become a valid keyword later, and then figure out that you
want it to act as though sizeof is allowed in preprocessor expressions.
A suitable diagnostic, for a smart compiler that does this, might
be something annoying like:

foo.c, line 123: warning: I handle "sizeof" the way you mean it
here, because "I M SMRT", but ANSI/ISO C compilers are not
required to, so your code may not work on other systems.

Of course, if you do "#define sizeof" -- e.g.:

#define sizeof(x) 3
#if sizeof(int) == 4
#undef sizeof

-- then other conditions apply.
 

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,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top