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.
Top ,.. top top … post! Keep the good work on !