The C Preprocessor



The job of the C Preprocessor is to process the source code before it is passed to the compiler. The preprocessor command is also known as directive.

The C Preprocessor

The C Program is often called as source code. Before the program is compiled, the source code goes through one process called preprocessor.

The preprocessor gets the source code (pr.C file) as input and creates expanded source code (pr.I file). This expanded source code is then passed to the compiler for compilation.

Following are the preprocessor directives:
  1. Macro expansion
  2. File inclusion
  3. Conditional Compilation
  4. Miscellaneous directives
Lets discuss these preprocessor directive one by one.

Macro expansion
Let us understand the macro expansion using an example.

Example:
#include<stdio.h>
#define TEN 10
void main()
{
 int a = 10;
 if (a == TEN)
 {
  printf("The value of a is 10");
 }
}
If we run the above example, we will get the output as "The value of a is 10".
In the above example, we have used macro definition. As we learnt before, before compilation process the Source code goes through preprocessing process. During preprocessing, the program is scanned from top to bottom. Every occurrence of TEN in the source code is replaced by 10.

Thus, after preprocessing  the program looks like give below,
#include<stdio.h>
void main()
{
 int a = 10;
 if (a == 10)
 {
  printf("The value of a is 10");
 }
}
The preprocessor directive ‘#define’ can also be used to define operators as shown below.
#define AND &&
#define OR ||

After the definition of these operators we can use AND instead of &&  and OR instead of || within the program. This increases the readability of the program.

The above explained macro is called as ‘Simple macro’. There is another form of macro called ‘Macros with Arguments’.
Let us understand ‘Macros with Arguments’ with the help of an example.

Example:
#include<stdio.h>
#define AREA (3.14  * a * a)
void main()
{
 int ar = AREA(10);
 printf("Area = %f", ar);
}
If we run the above example, we will get the output as “AREA = 314.000000”.

In the above example, we have used macros with arguments. As we learnt, before compilation process the Source code goes through preprocessing process. During preprocessing, the program is scanned from top to bottom. Every occurrence of AREA(10) in the source code is replaced by (3.14 * 10 * 10).
Thus, after preprocessing the program looks like give below.
#include<stdio.h>
void main()
{
 int ar = 3.14 * 10 * 10;
 printf("Area = %f", ar);
}
Macros can be split into multiple lines using back slash (‘\’) as shown below.
#define DISPLAY for(i=0;i<10;i++) \
   printf("This is a macro split into multiple lines");

File Inclusion
File inclusion directive causes one file to be included in another. We have already used file inclusion directive before. The preprocessor command for file inclusion looks like this:

#include “File name”
OR
#include <file name>

E.g. #include<stdio.h>

The above statement in C will include the file “stdio.h” in the program.

If the filename is enclosed within angle brackets, the file is searched for in the standard compiler include paths. If the filename is enclosed within double quotes, the search path is expanded to include the current source directory.

Conditional Compilation
The #if, #ifdef, #ifndef, #else, #elif and #endif directives can be used for conditional compilation.
If the macroname has been #defined, the block of code will be processed as usual.

If we use #if, #ifdef, #ifndef, #else, #elif or #endif directives, it will not be processed as usual. Using these directives we can have compiler to skip over part of a source code.

Let us understand the conditional compilation directives using an example.

Example:
#include<stdio.h>
void main()
{
 #ifdef YES
  Statement 1;
  Statement 2;
 #endif
 Statement 3;
}
In the above example, statement 1 and statement 2 would be processed only if we define macro ‘YES’ else it won’t be processed.
As seen in the above program, macro ‘YES’ has not been defined. Hence, only statement 3 would be processed.

Example:
#include<stdio.h>
#define YES
void main()
{
 #ifdef YES
  Statement 1;
  Statement 2;
 #endif
 Statement 3;
}
In the above example, statement 1, Statement 2 and Statement 3 would be processed as we have defined macro ‘YES’.

Example:
#include<stdio.h>
#define YES
void main()
{
 #ifdef YES
  Statement 1;
  Statement 2;
 #else
  Statement 3;
 #endif
}
The above example can be read as follows:
If macro ‘YES’ is defined then
Process Statement 1 and Statement 2
Else
Process Statement 3
The above example will process Statement 1 and Statement 2.

#ifndef (if not defined) is exactly opposite to #ifdef.
Example:
#include<stdio.h>
#define YES
void main()
{
 #ifndef YES
  Statement 1;
  Statement 2;
 #else
  Statement 3;
 #endif
}
The above example can be read as follows:
If macro ‘YES’ is not defined then
Process Statement 1 and Statement 2
Else
Process Statement 3
The above example will process Statement 3.

The #if directive can be used to test whether an expression evaluates to non zero or not. If the expression evaluates to non zero then the subsequent lines upto #else, #elif or #endif are compiled, otherwise they are skipped.

Example:
#include<stdio.h>
#define VALUE 5
void main()
{
 #if VALUE == 5
  Statement 1;
 #elif VALUE <=10
  Statement 2;
 #else 
  Statement 3;
 #endif 
}
In the above program, if VALUE == 5 returns true then Statement 1 would be processed, else if VALUE <= 10 returns true then Statement 2 would be processed else Statement 3 would be processed.

Miscellaneous directive
#undef directive causes a defined name to become undefined. In order to undefined the macro that has been defined earlier, the directive, #undef macro name can be used. Thus, #undef VALUE would cause the definition of VALUE to be removed from the system.
#pragma directive is another very special and useful directive. This directive is used to specify diverse options to the compiler. These options are specific for the platform and the compiler you use.
If the compiler does not support a specific argument for #pragma, it is ignored - no error is generated. #pragma startup and #pragma exit are most commonly used pragma directives.
#pragma startup allows you to specify a particular function that are called upon program startup (before the execution of main()).
#pragma exit allows you to specify a function that can be called just before the program terminates.

Example:
void display1();
void display2();
#pragma startup display1
#pragma exit display2
void main()
{
 printf(“I am in main”); 
}
void display1()
{
 printf(“I am in function1”);
}
void display2()
{
 printf(“I am in function2”);
}

Output:

I am in function1
I am in main
I am in function2

Please provide your valuable comments about this article or anything related to this website. It would really help me in improving the website.


Responses

0 Respones to "The C Preprocessor"

Post a Comment

 

Total Pageviews

Return to top of page Copyright © 2011 | Kuppam Engineering College Converted into Blogger Template by Mohan Murthy