1. | Welcome | ToC | FAQ | Resources | Courses | Projects | Mail Lists | Members | Misc |
2. | Fundamentals | Languages | Tools | Net | Core | Advanced |
3. | EoC | Java |
4. | Lessons |
5. | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |


Essence of C
10 - THE C PREPROCESSOR

The C Preprocessor

As defined by the ANSI standard, the C preprocessor contains the following directives:

#if  #ifdef  #ifndef  #else  #elif  #include  #define  #undef  #line  #error  #pragma

#define

#define defines an identifier (the macro name) and a string (the macro substitution) which will be substituted for the identifier each time the identifier is encountered in the source file.

Once a macro name has been defined, it may be used as part of the definition of other macro names.

If the string is longer than one line, it may be continued by placing a backslash on the end of the first line.

By convention, C programmers use uppercase for defined identifiers. Example macro #defines are:

     #define TRUE 1
     #define FALSE 0

The macro name may have arguments, in which case every time the macro name is encountered, the arguments associated with it are replaced by the actual arguments found in the program, as in:

     #define ABS(a) (a)<0 ? -(a) : (a)
     ...
     printf("abs of -1 and 1: %d %d", ABS(-1), ABS(1));

Such macro substitutions in place of real functions increase the speed of the code at the price of increased program size.

#error

#error forces the compiler to stop compilation. It is used primarily for debugging. The general form is:

     #error  error_message

When the directive is encountered, the error message is displayed, possibly along with other information (depending on the compiler).

#include

#include instructs the compiler to read another source file, which must be included between double quotes or angle brackets. Examples are:

     #include "stdio.h"
     #include <stdio.h>

which both instruct the compiler to read and compile the named header file.

If a file name is enclosed in angle brackets, the file is searched for as specified by the creator of the compiler. If the name is enclosed in double quotes, the file is searched for in an implementation-defined manner, which generally means searching the current directory. (If the file is not found, the search is repeated as if the name had been enclosed in angle brackets.)

Conditional Compilation - #if, #else, #elif, and #endif

Several directives control the selective compilation of portions of the program code, viz, #if, #else, #elif, and #endif.

The general form of #if is:

     #if constant_expression
     statement sequence
     #endif

#else works much like the C keyword else. #elif means "else if" and establishes an if-else-if compilation chain.

Amongst other things, #if provides an alternative method of "commenting out" code. For example, in

     #if 0
     printf("#d",total);
     #endif

the compiler will ignore printf("#d",total);.

#ifdef and #ifndef

#ifdef means "if defined", and is terminated by an #endif. #indef means "if not defined".

#undef

#undef removes a previously defined definition.

#line

#line changes the contents of __LINE__ (which contains the line number of the currently compiled code) and __FILE__ (which is a string which contains the name of the source file being compiled), both of which are predefined identifiers in the compiler.

#pragma

The #pragma directive is an implementation-defined directive which allows various instructions to be given to the compiler.

The # and ## Preprocessor Operators

The # and ## preprocessor operators are used when using a macro #define.

The # operator turns the argument it precedes into a quoted string. For example, given:

     #define mkstr(s) # s

the preprocessor turns the line

     printf(mkstr(I like C);

into

     printf("I like C");

The ## operator concatenates two tokens. For example, given:

     #define concat(a, b) a ## b

     int xy=10;
     printf("%d",concat(x, y);

the preprocessor turns the last line into:

     printf("%d", xy);

Predefined Macro Names

The ANSI standard specifies five built-in predefined macro names. These are:

     __LINE__ __FILE__ __DATE__ __TIME__ __STDC__

__LINE__ and __FILE__ have already been discussed.

__DATE__ and __TIME__ contain strings of the form month/date/year and hour/minute/second which represent the date and time of compilation.

__STDC__ contains the decimal constant 1, which means that the implementation conforms to the standard. If it contains any other number, the implementation varies from the standard.

Prior Chapter · Index · Next Chapter


Copyright © 1996, 1997, 1998. Last Update to This Page: 1998/10/24
This Page Maintained by: radar pangaean * * * Original Author: K.J.Bricknell
The MOST web site is built and maintained by the voluntary efforts/donations of our members.