The C preprocessor is a macro processor that is used automatically by the C compiler to transform your program before actual compilation (Proprocessor direcives are executed before compilation.). It is called a macro processor because it allows you to define macros, which are brief abbreviations for longer constructs. A macro is a segment of code which is replaced by the value of macro. Macro is defined by #define directive.

Preprocessing directives are lines in your program that start with #. The # is followed by an identifier that is the directive name. For example, #define is the directive that defines a macro. Whitespace is also allowed before and after the #.

The # and the directive name cannot come from a macro expansion. For example, if foo is defined as a macro expanding to define, that does not make #foo a valid preprocessing directive.

All preprocessor directives starts with hash # symbol.

List of preprocessor directives :

  1. #include
  2. #define
  3. #undef
  4. #ifdef
  5. #ifndef
  6. #if
  7. #else
  8. #elif
  9. #endif
  10. #error
  11. #pragma

1. #include

The #include preprocessor directive is used to paste code of given file into current file. It is used include system-defined and user-defined header files. If included file is not found, compiler renders error. It has three variants:

#include <file>

This variant is used for system header files. It searches for a file named file in a list of directories specified by you, then in a standard list of system directories.

#include "file"

This variant is used for header files of your own program. It searches for a file named file first in the current directory, then in the same directories used for system header files. The current directory is the directory of the current input file.

#include anything else

This variant is called a computed #include. Any #include directive whose argument does not fit the above two forms is a computed include.

2. Macro's (#define)

Let's start with macro, as we discuss, a macro is a segment of code which is replaced by the value of macro. Macro is defined by #define directive.

Syntax

#define token value  

There are two types of macros:

  1. Object-like Macros
  2. Function-like Macros

1. Object-like Macros

The object-like macro is an identifier that is replaced by value. It is widely used to represent numeric constants. For example:

#define PI 3.1415  

Here, PI is the macro name which will be replaced by the value 3.14. Let's see an example of Object-like Macros :

#include <stdio.h>  
#define PI 3.1415 
main() 
{  
   printf("%f",PI);  
}  

Output:

3.14000

2. Function-like Macros

The function-like macro looks like function call. For example:

#define MIN(a,b) ((a)<(b)?(a):(b))    

Here, MIN is the macro name. Let's see an example of Function-like Macros :

#include <stdio.h>  
#define MIN(a,b) ((a)<(b)?(a):(b))  
void main() {  
   printf("Minimum between 10 and 20 is: %d\n", MIN(10,20));    
}  

Output:

Minimum between 10 and 20 is: 10

Preprocessor Formatting

A preprocessing directive cannot be more than one line in normal circumstances. It may be split cosmetically with Backslash-Newline. Comments containing Newlines can also divide the directive into multiple lines.

for example, you can split a line cosmetically with Backslash-Newline anywhere:

/*
*/ # /*
*/ defi\
ne FO\
O 10\
20

is equivalent into #define FOO 1020.

3. #undef

To undefine a macro means to cancel its definition. This is done with the #undef directive.

Syntax:

#undef token  

define and undefine example

#include <stdio.h>  
#define PI 3.1415  
#undef PI  
main() {  
   printf("%f",PI);  
}  

Output:

Compile Time Error: 'PI' undeclared

4. #ifdef

The #ifdef preprocessor directive checks if macro is defined by #define. If yes, it executes the code.

Syntax:

#ifdef MACRO  
//code  
#endif

5. #ifndef

The #ifndef preprocessor directive checks if macro is not defined by #define. If yes, it executes the code.

Syntax:

#ifndef MACRO  
//code  
#endif  

6. #if

The #if preprocessor directive evaluates the expression or condition. If condition is true, it executes the code.

Syntax:

#if expression  
//code  
#endif  

7. #else

The #else preprocessor directive evaluates the expression or condition if condition of #if is false. It can be used with #if, #elif, #ifdef and #ifndef directives.

Syntax:

#if expression  
//if code  
#else  
//else code  
#endif

Syntax with #elif

#if expression  
//if code  
#elif expression  
//elif code  
#else  
//else code  
#endif  

Example

#include <stdio.h>  
#include <conio.h>  
#define NUMBER 1  
void main() {  
#if NUMBER==0  
printf("Value of Number is: %d",NUMBER);  
#else  
print("Value of Number is non-zero");  
#endif         
getch();  
}  

Output

Value of Number is non-zero

8. #error

The #error preprocessor directive indicates error. The compiler gives fatal error if #error directive is found and skips further compilation process.

C #error example

#include<stdio.h>  
#ifndef __MATH_H  
#error First include then compile  
#else  
void main(){  
    float a;  
    a=sqrt(7);  
    printf("%f",a);  
}  
#endif

9. #pragma

The #pragma preprocessor directive is used to provide additional information to the compiler. The #pragma directive is used by the compiler to offer machine or operating-system feature. Different compilers can provide different usage of #pragma directive.

Syntax:

#pragma token 

Example

#include<stdio.h>  
#include<conio.h>  
  
void func() ;  
  
#pragma startup func  
#pragma exit func  
  
void main(){  
printf("\nI am in main");  
getch();  
}  
  
void func(){  
printf("\nI am in func");  
getch();  
}  

Output

I am in func
I am in main
I am in func

Next - Simple and Static Assertion (assert)