COHERENT manpages

This page displays the COHERENT manpage for C preprocessor [Overview].

List of available manpages
Index


C preprocessor -- Overview

Preprocessing encompasses all  tasks that logically precede the translation
of  a program.   The preprocessor  processes  headers, expands  macros, and
conditionally includes or excludes source code.

Directives

The C preprocessor recognizes the following directives:

#if............Include code if a condition is true
#elif..........Include code if directive is true
#else..........Include code if preceding directives fail
#endif.........End of code to be included conditionally

#ifdef.........Include code if a given macro is defined
#ifndef........Include code if a given macro is not defined

#define........Define a macro
#undef.........Undefine a macro
#include.......Read another file and include it
#line..........Reset current line number

The  COHERENT preprocessor  also  recognizes the  directive #pragma,  which
performs implementation-specific  tasks.  See the Lexicon  entry on #pragma
for details.

A preprocessing  directive is always introduced by  the `#' character.  The
`#' must  be the first non-white  space character on a line,  but it may be
preceded by  white space and  it may be  separated from the  directive name
that follows it by one or more white space characters.

Preprocessing Operators

The Standard defines two operators that are recognized by the preprocessor:
the ``stringize'' operator #,  and the ``token-paste'' operator ##. It also
defines a new keyword associated with preprocessor statements: defined.

The operator # indicates that the following argument is to be replaced by a
string literal;  this literal names  the preprocessing token  that replaces
the argument.  For example, consider the macro:

    #define display(x) show((long)(x), #x)

When the preprocessor reads the line

    display(abs(-5));

it replaces it with the following:

    show((long)(abs(-5)), "abs(-5)");

The ## operator performs ``token pasting''  -- that is, it joins two tokens
together, to create a single token.  For example, consider the macro:

    #define printvar(x) printf("%d\n", variable ## x)

When the preprocessor reads the line

    printvar(3);

it translates it into:

    printf("%d\n", variable3);

In  the past,  token  pasting had  been  performed by  inserting a  comment
between the tokens to be pasted.  This no longer works.

Predefined Macros

The ANSI Standard describes the following macros that must be recognized by
the preprocessor:

    __DATE__  Date of translation
    __FILE__  Source-file name
    __LINE__  Current line within source file
    __STDC__  Conforming translator and level
    __TIME__  Time of translation

For more information on any one of these macros, see its entry.

Conditional Inclusion

The preprocessor will conditionally include lines of code within a program.
The directives  that include code  conditionally are defined in  such a way
that you  can construct a chain of inclusion  directives to include exactly
the material you want.

The preprocessor keyword defined  determines whether a symbol is defined to
the #if preprocessor directive.  For example,

    #if defined(SYMBOL)

or

    #if defined SYMBOL

is equivalent to

    #ifdef SYMBOL

except that it can be used in more complex expressions, such as

    #if defined FOO && defined BAR && FOO==10

defined is recognized only in lines beginning with #if or #elif.

Note that  defined is a preprocessor keyword,  not a preprocessor directive
or a C keyword.  You could,  for example, write a function called defined()
without any complaint from the C compiler.

The COHERENT preprocessor implicitly defines the following macros:

    __COHERENT__
    __MWC__
    __IEEE__
    __I386__

    _IEEE
    _I386
    MWC
    COHERENT

These can be used to include  conditionally code that applies to a specific
edition of COHERENT.  COHERENT 286 uses DECVAX floating-point code; whereas
COHERENT 386  uses IEEE.   If you were  writing code that  intensively used
floating-point  numbers  and you  wanted  to compile  the  code under  both
editions of COHERENT, you could write code of the form:

    #ifdef _DECVAX
        ...
    #elif _IEEE
        ...
    #endif

The C  preprocessor under  each edition of  COHERENT would ensure  that the
correct code was included for compilation.

Macro Definition and Replacement

The preprocessor  performs simple types of macro  replacement.  To define a
macro,  use  the  preprocessor  directive  #define identifier  value.   The
preprocessor scans the  translation unit for preprocessor tokens that match
identifier; when one is found, the preprocessor substitutes value for it.

Inclusion of Macros or Functions

The ANSI standard demands that every routine implemented as a macro also be
implemented as  a function, with  the exception of the  macro va_arg(). For
example,  COHERENT implements  the STDIO  routines toupper()  and tolower()
both as macros and functions.

By default,  COHERENT uses the macro  version of routines.  To  force it to
use the  function of a routine,  you must undefine the  macro version.  You
can do  that either  by using the  preprocessor instruction #undef  in your
code, or  by using the option  -U on the cc command  line.  For example, to
compel  COHERENT to  use  the function  version of  tolower(), include  the
statement

    #undef tolower

in your program, or include the argument

    -Utolower

on the cc command line.

cpp

Under COHERENT, C preprocessing is done  by the program cpp. The cc command
runs cpp as  the first step in compiling a  C program.  cpp can also be run
by itself.

cpp reads each input file;  it processes directives, and writes its product
on stdout.

If its -E option is not used, cpp also writes into its output statements of
the form #line n filename,  so that  the parser cc0  can connect  its error
messages and debugger output with  the original line numbers in your source
files.

See the Lexicon entry on cpp for more information.

See Also

C language,
cc,
cpp,
defined,
macro,
manifest constant,