Preprocessing

Preprocessing


The translator processes each source file in a series of phases. Preprocessing constitutes the earliest phases, which produce a translation unit. Preprocessing treats a source file as a sequence of text lines. You can specify directives and macros that insert, delete, and alter source text.

This document describes briefly just those aspects of preprocessing most relevant to the use of the Standard C library:

The macro __FILE__ expands to a string literal that gives the remembered filename of the current source file. You can alter the value of this macro by writing a line directive.

The macro __LINE__ expands to a decimal integer constant that gives the remembered line number within the current source file. You can alter the value of this macro by writing a line directive.

The name __func__ (added with C99) is effectively declared at the beginning of each function body as:

static const char __func__[] = "func_name";

where func_name is the name of the function.

A define directive defines a name as a macro. Following the directive name define, you write one of two forms:

  • a name not immediately followed by a left parenthesis, followed by any sequence of preprocessing tokens -- to define a macro without parameters
  • a name immediately followed by a left parenthesis with no intervening white space, followed by zero or more distinct parameter names separated by commas, followed by a right parenthesis, followed by any sequence of preprocessing tokens -- to define a macro with as many parameters as names that you write inside the parentheses

You can selectively skip groups of lines within source files by writing an if directive, or one of the other conditional directives, ifdef or ifndef. You follow the conditional directive by the first group of lines that you want to selectively skip. Zero or more elif directives follow this first group of lines, each followed by a group of lines that you want to selectively skip. An optional else directive follows all groups of lines controlled by elif directives, followed by the last group of lines you want to selectively skip. The last group of lines ends with an endif directive.

At most one group of lines is retained in the translation unit -- the one immediately preceded by a directive whose #if expression has a nonzero value. For the directive:

#ifdef X

this expression is defined (X), and for the directive:

#ifndef X

this expression is !defined (X).

A #if expression is a conditional expression that the preprocessor evaluates. You can write only integer constant expressions, with the following additional considerations:

  • The expression defined X, or defined (X), is replaced by 1 if X is defined as a macro, otherwise 0.
  • You cannot write the sizeof or type cast operators. (The translator expands all macro names, then replaces each remaining name with 0, before it recognizes keywords.)
  • The translator may be able to represent a broader range of integers than the target environment.
  • The translator represents type int the same as long, and unsigned int the same as unsigned long.
  • The translator can translate character constants to a set of code values different from the set for the target environment.

An include directive includes the contents of a standard header or another source file in a translation unit. The contents of the specified standard header or source file replace the include directive. Following the directive name include, write one of the following:

  • a standard header name between angle brackets
  • a filename between double quotes
  • any other form that expands to one of the two previous forms after macro replacement

A line directive alters the source line number and filename used by the predefined macros __FILE__ and __FILE__. Following the directive name line, write one of the following:

  • a decimal integer (giving the new line number of the line following)
  • a decimal integer as before, followed by a string literal (giving the new line number and the new source filename)
  • any other form that expands to one of the two previous forms after macro replacement

Preprocessing translates each source file in a series of distinct phases. The first few phases of translation: terminate each line with a newline character (NL), convert trigraphs to their single-character equivalents, and concatenate each line ending in a backslash (\) with the line following. Later phases process include directives, expand macros, and so on to produce a translation unit. The translator combines separate translation units, with contributions as needed from the Standard C library, at link time, to form the executable program.

An undef directive removes a macro definition. You might want to remove a macro definition so that you can define it differently with a define directive or to unmask any other meaning given to the name. The name whose definition you want to remove follows the directive name undef. If the name is not currently defined as a macro, the undef directive has no effect.


See also the Table of Contents and the Index.

Copyright © 1992-2006 by P.J. Plauger and Jim Brodie. All rights reserved.

Last modified: 2013-12-21



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus