C Programming IT Programming Tutorials

Preprocessor Directives

Preprocessing is the step before compilation, which is done by the preprocessor. It is also known as a macro processor which defines macros, the replacement word or abbreviation for the longer statements.
The Preprocessor Directives begin with # and are followed by directives such as define, undef, ifndef, etc. Now we will learn more about different types of Preprocessor Directives.

Types of Preprocessor Directives:

1. File Inclusion

2. Macro Expansion

3. Conditional Directives

File Inclusion

 The #include directive is used to include the mentioned file in the current file. If the file is not found, it will produce a compilation error.

Two types of #include files are used 
 #include<file> such as #include<stdio.h>, #include<conio.h>, #include<math.h> etc
 These directories inform the C preprocessor (CPP) to include the mentioned system-defined file in the current file.

#include”filename.h”
The above directories inform the CPP to include user-defined files in the current source file and the extern function is an example of file inclusion.

Macro Expansion

In Macro Expansion the macro or the instances of the variable are replaced by the value. This provides better readability for declaring numeric constants.
For example:

#define PI 3.14
#define Arr_size 20
#define var1_length 10
#undef PI

The undef directive removes or cancels the value defined by #define

Example 4:

Explanation:

In the above example, all the instances of var1_length are replaced with the value 10, then undef will remove the value of var1_length and when we try to print the var1_length after undef, it will produce an error.

Conditional Preprocessor Directives

#if,

   #elif, #else, #endif,  #ifdef,  #ifndef are all conditional directives.

Syntax:

 #if (conditional expression)
    statements;
 #elif (conditional expression)
    statements;
 #else
    statements;
 #endif

The #if, #elif is almost similar to normal decision control statements. If the condition is true, the following statements will be executed.

 To terminate the conditional directives, #endif statements are used

 The #ifdef implies if defined, the following statements will be executed and #ifndef implies if mentioned symbol or value is not defined, the following statements will be executed.

Example 1:

Explanation:

In the above example, it executes the statement following #ifndef since age is not defined and once age is defined with the value 25 then we terminate conditional directives properly with endif.
Aftert that #if checks the condition, here the condition becomes false so it executes #elif which is nothing but else if checks another condition, here 25>20, the condition is true and prints eligible to apply and prints age value.

Miscellaneous Preprocessor Directives

#error, #pragma, and #line are miscellaneous directives.
To generate the error message and skip further compilation process we use the
#error error-message.

Example 2:

Explanation:

Since the value of a is not defined, it displays error message and skip the compilation of the following codes.

#pragma directives

We use #pragma directives to give special instructions to the compiler which enable specific features.
There are different # pragma directives available according to the compiler.
Some of the #pragma directives supported by the turbo C++ compiler are

#pragma startup
#pragma exit and
#pragma warn - #pragma warn -rvl
#pragma warn -par
#pragma warn -rch

It first executes the startup function then the main and finally executes the exit function.

To suppress the warnings such as return value, parameter never used and unreachable code, we can use the #pragma warn directive.

Example 3:

Explanation:

When all the #pragma directives are not used, it will produce warning such as parameter never used(b), unreachable code (since it will not execute outputfn() call which is given after return statement), and no return value warning(since outputfn with return-type int, does not return any value).
Example 4:

Explanation: The function init is given as a startup function using pragma directive, so it executes first then the main function, and finally executes the exit function.

#line Directives

If multiple files are rearranged or combined from multiple sources to intermediate files using a program, the line directive informs the compiler about the source file and line number from where it originated.

To change file names and line numbers during preprocessing we use three variants of #line directives.
#line integer
eg: #line 130

The number 130 represents the line number of the following line of input, in an original source file.

#line integer file-name
This specifies the name of the following line of input that came from the source file and its line number.

#line macro-calls
for example

#define Linenumber 50
#define filename(f) #f
#line Linenumber filename(newfilename.h)

The Linenumber has a value of 50 and the filename stringizes the passed filename or parameter. After compilation, the successive line will have Linenumber 100 and mentioned filename.
Example 5:

Explanation:
Once the linenumber and filename are set using the directives(#line 10 and #line 20 “hello.c”), the compiler ignores the previous values and continues with the new values.

Operators used in Preprocessor Directives

We use preprocessor operators in the creation of macros. 

Macro continuation(\) operator

 Stringize(#) operator

 Token pasting(##) operator

 Defined() operator

Macro continuation(\) operator

 The macro is usually a simple value or expression but when it is too long (\) macro continuation operator is used.

#define welcome_msg(a,b) \
                     printf(#a " and " #b ", Hello welcome!\n");

Where (#) is the Stringize operator, used to convert a macro to string constant. It is used only in specified parameter lists or macro. 

Example 6:

<script src="https://gist.github.com/GeethaaSrinivasan/be080cee245e3faa377fd44188fbd33a.js"></script>

Explanation:  In the above example we use the (\ )operator to combine macro with its value which is lengthy. The (#) operator converts macro to string and before compilation whenever it finds the macro it replaces it with its value. 

Token pasting(##) operator

To combine two different tokens into a single token we use this operator.

Example 7:

Explanation:

The (#) stringize operator which converts to string and (##)token-pasting operator which converts to string and assign equivalent value. At first we assign value 40 to var10 pre-increment and print.

Then we apply macro for varno(10) which replaces with printf(“var10=%d”,var10) and produces the above output.

Defined() operator

To determine whether the identifier is defined or not we use, the defined() operator. If defined, the value is true(non-zero) and if not defined, the value is false(zero).
Example 8:

Explanation:

If msg is not defined, define msg with value welcome.

Recommended Articles

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *