The Preprocessor Directives in C - ByteScout
  • Home
  • /
  • Blog
  • /
  • The Preprocessor Directives in C

The Preprocessor Directives in C

The C preprocessor directives are executed before the compilation of a program. It is not a part of the compiler and it is a separate step in the compilation process. It instructs the compiler to do the required pre-processing before the actual compilation of a program. So it is just a text substitution tool. There are several steps present in between writing a program and executing a program.

Interview Questions Digital Transformation

How does the preprocessor work?

The programmer writes a source code and stores it in a file program. c. This file is then processed by preprocessors and an expanded source code file gets generated named as a program. The compiler compiles this expanded source code file and generates an object code file named the program. obj. This object code file and an object code of library functions are linked by the linker. This linking generates an executable file program.exe. The required results are obtained by executing the program.exe file.

The hash symbol (#) is the beginning of all preprocessor commands. Without preprocessors, our source code is not ready for compilation. The source code is processed by the preprocessors. This process is responsible for the expansion of source code. The compiler compiles this expanded file of source code.

Important preprocessor directives

Sr. no. Processor Directives Description
1 #define Substitution of a processor macro.
2 #include Insertion of the mentioned header file.
3 #undef Undefining of a preprocessor macro.
4 #ifdef If the mentioned macro is defined, then it returns true.
5 #ifndef If the mentioned macro is not defined, then it returns true.
6 #if Testing of a compile-time condition.
7 #else Testing of a compile-time condition when the condition in #if is false.
8 #elif This one preprocessor includes both #else and #if.
9 #endif Ending of preprocessor condition.
10 #error On stderr, it prints an error message.
11 #pragma Specialized command is issued by it using a standardized method.

 

Predefined Macros

Sr. no. Macro Description
1 __DATE__ It returns the current date. The format of this date is ‘MMM DD YYYY’.
2 __TIME__ It returns the current time. The format of this character string time literal is ‘HH:MM: SS’.
3 __FILE__ It contains the current filename. This filename is in a string literal format.
4 __LINE__ It contains the current line number. This filename is in a decimal constant format.
5 __STDC__ If the compiler complies with the ANSI standard then it is defined as 1.

 

The below program demonstrates the use of predefined macros:

#include <stdio.h>
int main(void)
{
printf("The current file is: %s\n", __FILE__);
printf("The current line is: %s\n", __LINE__);
printf("The current date is: %s\n", __DATE__);
printf("The current time is: %s\n", __TIME__);
printf("The ANSI standard is: %s\n", __STDC__);
return 0;
}

The output is as below:

The current file is a demo.c
The current line is: 6
The current date is: Dec 18 2020
The current time is: 17:51:52
The ANSI standard is: 1

Preprocessor Operators

Sr. no. Operators Description
1 \ It is the macro continuation operator. A macro becomes too long to confine in a single line after using it.
2 # It is the number-sign or stringize operator. A macro parameter converts into a string constant.
3 ## It is the token pasting operator. It combines two arguments. Two separate tokens to be joined into a single token in a macro definition by it.
4 defined() It is the defined operator. It is used in a constant expression. It determines if an identifier is defined using #define.

 

The below program demonstrates the use of preprocessor operators such as #, \ and ##:

#include <stdio.h>
# define message (first, second) printf(#first " and " #second" both test the code.\n" )
int main(void)
{
message (The Developer , tester);
return 0;
}

 

The output is as below:

The Developer and tester both test the code.

#include <stdio.h>
# define tokenno(n) printf("token" #n " = %d", token##n)
int main(void)
{
int token24=40;
tokenno(24);
return 0;
}

 

The output is as below:

token24 = 40

The Defined () Operator

It is used in constant expressions. It is used to determine if an identifier is defined using #define. If the specified identifier is defined, the value is true (non-zero) otherwise the value is false (zero). The defined operator is given as follows:

#include <stdio.h>
#if !defined(STRING)
#define STRING "I am a developer."
#endif
int main(void)
{
printf("The string is: %s\n", STRING);
return 0;
}

 

The output is as below:

The string is: I am a developer.

 

Parameterized Macros

The parameterized macros can simulate functions and can also handle parameters. Consider the following function:

int cube(int number)
{
return number*number*number* ;
}

 

Now, consider a macro as below:

#define cube(number) ((number)*(number)*(number))

The macros with arguments are always defined by using the #define directive. The parentheses contain an argument list. So, both macro and function above perform the same task. The spaces between the macro name and an open parenthesis give an error.

The below program demonstrates the implementation of the parameterized macro:

#include<stdio.h>
#define COMPARE (firstnumber,secondnumber) ((firstnumber)>(secondnumber)?(firstnumber):(secondnumber))
int main(void)
{
printf("The bigger number is: %d",COMPARE(10,20));
return 0;
}

The output is as below:

The bigger number is: 20

Macro preprocessor directives

It is a named piece of code in the program. When the compiler gets this name, the name is replaced with the actual code which belongs to it. The best example of macros is the #define preprocessor directive. This directive defines a macro.

Consider the program below:

#include <stdio.h>
//definition of MACRO directive
#define COUNT 4
int main(void)
{
inti;
for (i=0;i<=COUNT;i++)
{
printf("The number is: %d \n",i);
}
return 0;
}

The output is as below:

The number is: 0
The number is: 1
The number is: 2
The number is: 3
The number is: 4

In the above program, the word COUNT is replaced by number 4. The word COUNT is working as a macro template. The number 4 is working as a macro expansion. There is no need to put a semi-colon (;) at the end of the macro definition.

 

Argument passing using macros

The arguments can be passed to macros. Consider the program below:

#include <stdio.h>
//definition of MACRO directive
#define VOLUME (length, breadth, height) (length*breadth*height)
int main(void)
{
int length= 4, breadth=5, height=6, volume;
volume= VOLUME(length, breadth, height);
printf("The volume of a cube is: %d sq.unit",volume);
return 0;
}

The output is as below:

The volume of a cube is: 120 sq. unit

In the above program, VOLUME (length, breadth, height) is replaced by the statement (length*breadth*height) when the compiler encounters it. After this, values are passed to the macro template and it becomes VOLUME (4, 5, 6). So, the statement (length*breadth*height) becomes (4*5*6) and gives the required result.

File inclusion preprocessor directives

These preprocessor directives include a file in the source code with help of the compiler. This directive has two types.

The header or standard files includes printf(), scanf(), and other similar functions. Different header files have different functions. The standard I/O functions are present in theiostream.h header file. Similarly, the standard string-related functions are present in the string.h header file. Without these preprocessor directives, the functions mentioned above will not work. The syntax is as below:

#include <file_name>
The file_nameis the name of a file we needed with the related functions.

The program below demonstrates the implementation of the header or standard files:

#include <stdio.h>
int main(void)
{
printf("I am a developer.");
return 0;
}

The output is as below:

I am a developer.

The < and > brackets instruct the compiler to search the mentioned file in the standard directory.

The user-defined files are used to break large code and include the required files only at the required place. The syntax is as below:

#include "file_name"

The program below demonstrates the implementation of the user-defined files:

#include "stdio.h"
int main(void)
{
printf("I am a developer.");
return 0;
}

The output is as below:

I am a developer.

 

Conditional compiling preprocessor directives

These directives either compile or skip a specific part of the source code. The working of these directives is dependent upon the conditions mentioned in them. These directives include #if, #elif, #else, #endif, #ifdef. The syntax is as below:

#if Macro_Conditions
conditional_statements
#elifMacro_Conditions
conditional_statements
#else Macro_Conditions
conditional_statements
#endif

The program below demonstrates the implementation of conditional compiling preprocessor directives:

#include <stdio.h>
int main(void)
{
intfirstnumber,secondnumber;
printf("Enter two numbers:\n");
scanf("%d%d",&firstnumber,&secondnumber);
#if 3>9
printf("Sum %d",firstnumber+secondnumber);
#else
if(firstnumber == secondnumber)
printf("Both number are same.");
else if(firstnumber>secondnumber)
printf("The larger numbers is %d",firstnumber);
else
printf("The larger number is %d",secondnumber);
#endif
return 0;
}

The output is as below:

Enter two numbers:
6 8
The larger number is 8.

 

Other preprocessor directives

Some preprocessor directives are not used regularly. The compiler can skip them if they are not defined. Such directives are as below:
#undef directive:

This directive undefines a macro if it exists. The syntax for this is:

#undefMacro_name
e.g. #undef LIMIT

#pragma directives:

This is a special purpose directive. The main function of this directive is to turn on and off some features. These directives can specify the functions too.

#Pragma startup and #pragma exit directives

These directives redirect the flow of compilation of program towards the functions which are required just before program control passes to main and just before control returns to main. The program below demonstrates the implementation of conditional #pragma directives:

#include<stdio.h>
voidfirstfunction();
voidsecondfunction();
#pragma startup firstfunction #pragma startup secondfunction
voidfirstfunction()
{
printf("Inside the first function.\n");
}
voidsecondfunction()
{
printf("Inside the second function.\n");
}
int main(void)
{
voidfirstfunction();
voidsecondfunction();
printf("Inside the main function.\n");
return (0);
}

The output is as below:

Inside the first function.
Inside the main function.
Inside the second function.

#pragma warn directives:

These directives are used to hide the warning messages. Generally, these warning messages are created during the compilation of a program. Types of these directives are as below:

  1. #pragma warn -rvl: If the function should have to return a value but that function is unable to return a value then a warning message is generated. This directive is used to hide this type of warning message.
  2. #pragma warn -par: If the parameters are passed to a function and those parameters are not used by that function then a warning message is generated. This directive is used to hide this type of warnings.
  3. #pragma warn -rch: If a part of the source code is unreachable. For example, code after return line. Then a warning message is generated. This directive is used to hide this type of warnings.

Conclusion

Thus, in this tutorial, we have seen various preprocessor directives provided by C language along with their examples.  The preprocessor directives help us to write more efficient programs and more readable programs to some extent.

 

   

About the Author

ByteScout Team ByteScout Team of Writers ByteScout has a team of professional writers proficient in different technical topics. We select the best writers to cover interesting and trending topics for our readers. We love developers and we hope our articles help you learn about programming and programmers.  
prev
next