[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]  

Conditionals and Macros

Conditionals are useful in connection with macros or assertions, because those are the only ways that an expression's value can vary from one compilation to another. A `#if' directive whose expression uses no macros or assertions is equivalent to `#if 1' or `#if 0'; you might as well determine which one, by computing the value of the expression yourself, and then simplify the program.

For example, here is a conditional that tests the expression `BUFSIZE == 1020', where `BUFSIZE' must be a macro.

#if BUFSIZE == 1020
  printf ("Large buffers!\n");
#endif /* BUFSIZE is large */

(Programmers often wish they could test the size of a variable or data type in `#if', but this does not work. The preprocessor does not understand sizeof, or typedef names, or even the type keywords such as int.)

The special operator `defined' is used in `#if' expressions to test whether a certain name is defined as a macro. Either `defined name' or `defined (name)' is an expression whose value is 1 if name is defined as macro at the current point in the program, and 0 otherwise. For the `defined' operator it makes no difference what the definition of the macro is; all that matters is whether there is a definition. Thus, for example,

#if defined (vax) || defined (ns16000)

would succeed if either of the names `vax' and `ns16000' is defined as a macro. You can test the same condition using assertions (see section Assertions), like this:

#if #cpu (vax) || #cpu (ns16000)

If a macro is defined and later undefined with `#undef', subsequent use of the `defined' operator returns 0, because the name is no longer defined. If the macro is defined again with another `#define', `defined' will recommence returning 1.

Conditionals that test whether just one name is defined are very common, so there are two special short conditional directives for this case.

#ifdef name
is equivalent to `#if defined (name)'.
#ifndef name
is equivalent to `#if ! defined (name)'.

Macro definitions can vary between compilations for several reasons.

[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]