Skip to main content

28. Preprocessor

 

C Preprocessor

The C preprocessor is a micro processor that is used by compiler to transform our code before compilation. It is called micro preprocessor because it allows us to add macros. It is not a part of the C compiler. It is a text substitution tool.

C Preprocessor Directives

All preprocessor directives starts with hash # symbol. Some of the preprocessor directives are :

  • #include
  • #define
  • #undef
  • #ifdef
  • #ifndef
  • #if
  • #else
  • #elif
  • #endif
  • #error
  • #pragma

C Macros

A macro is a segment of code which is replaced by the value of macro. Macro is defined by #define directive. There are two types of macros:

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

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.14

Here, PI is the macro name which will be replaced by the value 3.14.

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.

C Predefined Macros

Some predefined macros that can be used in C program are

MacroDescription
__DATE__represents current date in "MMM DD YYYY" format.
__TIME__represents current time in "HH:MM:SS" format.
__FILE__represents current file name.
__LINE__represents current line number
__STDC__It is defined as 1 when compiler complies with the ANSI standard.

#include <stdio.h>
int main()
{
   printf("File: %s\n", __FILE__);
   printf("Date: %s\n", __DATE__);
   printf("Time: %s\n", __TIME__);
   printf("Line: %d\n", __LINE__);
   printf("STDC: %d\n", __STDC__);
   return 0;
}

Output :

File: 27.c
Date: Sep 8 2021
Time: 20:36:52
Line: 7
STDC: 1

#include

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

By the use of #include directive, we provide information to the preprocessor where to look for the header files. There are two variants to use #include directive.

  1. #include <filename>
  2. #include "filename"

The #include <filename> tells the compiler to look for the directory where system header files are held. In UNIX, it is \usr\include directory.

The #include "filename" tells the compiler to look in the current directory from where program is running.

  • In #include directive, comments are not recognized. So in case of #include <a//b>, a//b is treated as filename.
  • In #include directive, backslash is considered as normal text not escape sequences. So in case of #include <a\nb>, a\nb is treated as filename.
  • We can use only comment after filename otherwise it will give error.

#define

The #define preprocessor directive is used to define constant or micro substitution. It can use any basic data type.

#include <stdio.h>
#define PI 3.14
#define MIN(a, b) ((a)<(b)?(a):(b))
int main()
{
   printf("Value of Pi = %f\n", PI);
   printf("Minimum between 10 and 20 is %d: ", MIN(10, 20));
   return 0;
}

Output :

Value of Pi = 3.140000
Minimum between 10 and 20 is 10

#undef

The #undef preprocessor directive is used to undefine the constant or macro defined by #define.

#include <stdio.h>
#define PI 3.14
#undef PI
int main()
{
   printf("Value of Pi = %f\n", PI);
   return 0;
}

Output :

error: 'PI' undeclared

#ifdef

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

#include <stdio.h>
#define NoInput
int main()
{
   int n;
   #ifdef NoInput
   n = 7;
   #endif
   printf("Value of a: %d", n);
   return 0;
}

Output :

Value of n: 7

#ifndef

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

#include <stdio.h>
#define NoInput
int main()
{
   int m = 1;
   #ifndef Input
   m = 25;
   #endif
   printf("Value of m: %d", m);
   return 0;
}

Output :

Value of m: 1

#if

The #if preprocessor directive evaluates the expression or condition. If condition is true, it executes the code otherwise #elseif or #else or #endif code is executed.

#include <stdio.h>
#define Num 16
int main()
{
   #if (Num == 16)
   printf("Value of num is: %d", Num);
   #endif
   return 0;
}

Output :

Value of num is: 16

#else

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

#include <stdio.h>
#define Num 16
int main()
{
   #if (Num == 0)
   printf("Value of num is: %d", Num);
   #else
   printf("Value of num is: %d", Num);
   #endif
   return 0;
}

Output :

Value of num is: 16

#error

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

#include <stdio.>
int main()
{
   #ifndef PI
   #error Value of PI is not defined
   #else
   printf("Value of PI is %f", PI);
   #endif
   return 0;
}

Output :

Compile Time Error: Value of PI is not defined

But, if we define PI, it does not gives error.

#include <stdio.>
#define PI 3.14
int main()
{
   #ifndef PI
   #error Value of PI is not defined
   #else
   printf("Value of PI is %f", PI);
   #endif
   return 0;
}

Output :

Value of PI is 3.140000

#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.

Comments