Contents|Index|Previous|Next
Conditionals
and macros
Conditionals
are useful in connection with macros or assertions, be-cause 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
#if1
or #if0;
you might as well determine which one, by computing the value of the expression
yourself, and then simplify the program.
For
example, what follows is a conditional statement that tests the expression
BUFSIZE==1020,
where BUFSIZE
must be a macro.
#if BUFSIZE == 1020
printf ("Large buffers!\n");
#endif /* BUFSIZE is large */
Note:
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, as in the following example.
#if defined (vax) || defined (ns16000)
This statement
would succeed if either of the names vax
and ns16000
is defined as a macro. You can test the same condition using assertions
(see Assertions),
like the following example.
#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 Invoking
the C preprocessor.
Top|Contents|Index|Previous|Next