Whole document tree
    

Whole document tree

The C Preprocessor: Conditionals-Macros
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5.4 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 1.5.5 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.

  • Some macros are predefined on each kind of machine. For example, on a Vax, the name `vax' is a predefined macro. On other machines, it would not be defined.

  • Many more macros are defined by system header files. Different systems and machines define different macros, or give them different values. It is useful to test these macros with conditionals to avoid using a system feature on a machine where it is not implemented.

  • Macros are a common way of allowing users to customize a program for different machines or applications. For example, the macro `BUFSIZE' might be defined in a configuration file for your program that is included as a header file in each source file. You would use `BUFSIZE' in a preprocessing conditional in order to generate different code depending on the chosen configuration.

  • Macros can be defined or undefined with `-D' and `-U' command options when you compile the program. You can arrange to compile the same source file into two different programs by choosing a macro name to specify which program you want, writing conditionals to test whether or how this macro is defined, and then controlling the state of the macro with compiler command options. See section 1.9 Invoking the C Preprocessor.

Assertions are usually predefined, but can be defined with preprocessor directives or command-line options.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by root on January, 30 2002 using texi2html