My Blog
Articles related to programming, computer science, technology and research.

23/04/2016 Categories: C Programming. 2 Comments on Preprocessor Directives in C

C provides many features like structures, unions and pointers. Another unique feature of the C language is the preprocessor. The C preprocessor provides several tools that are not present in other high-level languages.


The programmer can use these tools to make his program easy to read, easy to modify, portable and more efficient. The preprocessor is a program that processes the source code before it passes through the compiler.


Preprocessor directives are placed in the source program before the main line. Before the source code passes through the compiler, it is examined by the preprocessor for any preprocessor directives. If there are any, appropriate actions are taken and then the source program is handed over to the compiler.


All the preprocessor directives follow special syntax rules that are different from the normal C syntax. Every preprocessor directive begins with the symbol # and is followed by the respective preprocessor directive. The preprocessor directives are divided into three categories. They are:

  1. Macro Substitution Directives
  2. File Inclusion Directives
  3. Compiler Control Directives


Macro Substitution Directives


Macro substitution is a process where an identifier in a program is replaced by a predefined string composed of one or more tokens. The preprocessor accomplishes this task under the direction of #define statement. This statement, usually known as a macro definition takes the following form:




If this statement is included in the program at the beginning, then the preprocessor replaces every occurrence of the identifier in the source code by the string.


Note: Care should be taken that there is no space between the # and the word define. Also there should be atleast a single space between #define and the identifier and between the identifier and the string. Also, there will be no semi-colon at the end of the statement.


There are different forms of macro substitution. The most common are:

  1. Simple macro substitution
  2. Argumented macro substitution
  3. Nested macro substitution


Simple Macro Substitution


The simple macro substitutions are generally used for declaring constants in a C program. Some valid examples for simple macro substitution are:




Whenever the preprocessor comes across the simple macros, the identifier will be replaced with the corresponding string. For example, in a C program, all the occurrences of PI will be replaced with 3.1412.


Argumented Macro Substitution


The preprocessor allows us to define more complex and more useful form of substitutions. The Argumented macro substitution takes the following form:




Care should be taken that there is no space between the identifier and the left parentheses. The identifiers arg1, arg2, …. , argn are the formal macro arguments that are analogous to the formal arguments in a function definition.


In the program, the occurrence of a macro with arguments is known as a macro call. When a macro is called, the preprocessor substitutes the string, replacing the formal parameters with actual parameters.


For example, if the Argumented macro is declared as shown below:




and the macro is called as shown below:




Then the preprocessor will expand the above statement as:




Nested Macro Substitution


We can use one macro inside the definition of another macro. Such macros are known as nested macros. Example for a nested macro is shown below:





File Inclusion Directives


The external files containing functions or macro definitions can be linked with our program so that there is no need to write the functions and macro definitions again. This can be achieved by using the #include directive. The syntax for this directive is as shown below:




We can use either of the above statements to link our program with other files. If the filename is included in double quotes, the file is searched in the local directory. If the filename is included in angular brackets, then the file is searched in the standard directories.


Compiler Control Directives


Following are the compiler control directives:


Directive Purpose
#ifdef Test for a macro definition
#endif Specifies the end of #if
#ifndef Tests whether a macro is not defined
#if Test a compile-time condition
#else Specifies alternative when #if fails


These compiler control directives are used in different situations. They are:


Situation 1


You have included a file containing some macro definitions. It is not known whether a certain macro has been defined in that header file. However, you want to be certain that the macro is defined.


This situation refers to the conditional definition of a macro. We want to ensure that the macro TEST is always defined, irrespective of whether it has been defined in the header file or not. This can be achieved as follows:



DEFINE.H is the header that is supposed to contain the definition of TEST macro. The directive #ifndef TEST searches the definition of TEST in the header file and if it is not defined, then all the lines between the #ifndef and the corresponding #endif directive are executed in the program.


Situation 2


Suppose a customer has two different types of computers and you are required to write a program that will run on both the systems. You want to use the same program, although a certain lines of code must be different for each system.


The main concern here is to make the program portable. This can be achieved as shown below:



If we want to run the program on a IBM PC, we include the directive #define IBM_PC, otherwise we won’t.


Situation 3


You are developing a program for selling in the open market. Some customers may insist on having certain additional features. However, you would like to have a single program that would satisfy both types of customers.


This situation is similar to the above situation and therefore the control directives take the following form:



Group-A lines are included if the customer ABC is defined. Otherwise, Group-B lines are included.


Situation 4


Suppose if you want to test a large program, you would like to include print calls in the program in certain places to display intermediate results and messages in order to trace the flow of execution and errors.


For this purpose we can use #if and #else directive as shown below:



ANSI Preprocessor Directives


The ANSI committee has added some more preprocessor directives to the existing list. They are:


Directive Purpose
#elif Provides alternative test facility
#pragma Specifies compiler instructions
#error Stops compilation when an error occurs


#elif   Directive


The #elif directive enables us to establish an “if…else…if” sequence for testing multiple conditions. The syntax is as shown below:



#pragma  Directive


The #pragma directive is an implementation oriented directive that allows the user to specify various instructions to be given to the compiler. Syntax is as follows:



Where name is the name of the pragma we want. For example, under Microsoft C, #pragma loop_opt(on)  causes loop optimization to be performed.


#error  Directive


The #error directive is used to produce diagnostic messages during debugging. The general format is:



When the #error directive is encountered by the compiler, it displays the error message and terminates the program.





Preprocessor Operations


Stringizing Operator #


ANSI C provides an operator # called stringizing operator to be used in the definition of macro functions. This operator converts a formal argument into a string. For example, if the macro is defined as follows:



and somewhere in the program the statement is written as: sum(a+b); then the preprocessor converts this line as shown below:



Token Pasting Operator ##


The token pasting operator ## defined by ANSI enables us to combine two tokens within a macro definition to form a single token.

Related Links:


You can follow any responses to this entry through the RSS 2.0 feed.

I like the article

Thanks for the terrific guide

Scroll Up