top

Search

C Tutorial

.

UpGrad

C Tutorial

C/C++ Preprocessors

Overview

Preprocessor programs, also known as the preprocessor derivatives, are statements used in C/C++ programming language that are processed before the preprocessor executes the compilation of the code. These directives usually start with a ‘#’ and are implemented to alter source codes before their compilation occurs. 

Having understood what is preprocessor in C and C++, let’s look at the briefs of various preprocessor directives.

List of Preprocessor Directives

Here is the list of commonly used directives of C/C++ preprocessors.

#define: Helps define a macro

#undef: It undefines a macro

#include: It lets you include a file in the source code program

#ifdef: It is used to include a code section if a specific macro is defined by #define

#ifndef: It includes a code section if a specific macro is  not defined by #define

#endif: It indicates the end of #endif

#if: It checks for the specified condition

#else: It executes the alternate code when #if fails

 #error: It stops program compilation

#warning: It continues the compilation process by displaying warning messages in the console window.

#region and #endregion: They increase the readability of code sections using the expansion and collapse features.

Navigating the Process Flow of Preprocessor Directives

Process flow of preprocessor directives

Step-1: First, a developer writes a C program, and the program checks for the availability of any preprocessor directives.

Step-2: If the preprocessor directives are available, the program will undergo the action event of the pre-processor, and the C compiler would generate the object code. Subsequently, the linker executes the code.

Step-3: If preprocessor directives are unavailable, the process flow reaches the compiler. After the linker executes the code, the compiler will generate the object code.

Types of Preprocessor Directives

Here’s the list of 4 major types of preprocessor directives in C.

  1. Macros

  2. File Inclusion

  3. Conditional Compilation

  4. Other directives 

Let’s discuss them in detail.

1) Macros

The macros in C/C++ are parts of code that are assigned some name. Whenever the compiler encounters this name, it substitutes the name with the actual code piece. The ‘#define’ directive helps you to define a macro. You can’t redefine those macros in C++ programs.

Here’s the syntax of the macro:

#define token value

A few examples of macros are __cplusplus, __DATE__, __TIME__, __FILE__, __LINE__, __STDC__, and __STDC_HOSTED__. 

Let’s look at the following example to understand how the macro works as one of the C/C++ preprocessors.

#include <stdio.h>
#define MIN(x, y) ((x) < (y) ? (x) : (y))
 
int main() 
{
int n1 = 5;
int n2 = 10;
 
int min_numb = MIN(n1, n2);
 
printf("The minimum number between %d and %d is %d\n", n1, n2, min_numb);
  
return 0;
}

Output:

The minimum number between 5 and 10 is 5

In the above program, we define macro MIN(x, y), which accepts two arguments x and y. It implements the ternary operator to return the minimum of two values. In the main function, two variables, n1 and n2, are declared. The MIN macro is implemented to find the minimum of those two numbers and assign its value to min_numb. Lastly, the program displays the output.

2) File Inclusion

The file inclusion preprocessor directives in C inform the compiler to include a file inside the source code program.

A user can include two types of files in a C/C++ program:

i. Standard header files

These files hold definitions of pre-defined functions such as printf(), scanf(), etc. Various functions are declared in various header files. For example, the #include preprocessor directive is useful to include the header files in a C/C++ program.  The standard I/O functions are contained in the ‘iostream’ file.

Here’s the syntax of #include preprocessor directive:

#include <file_name>

where file_name represents the name of the header file to be included in the program. The ‘<‘ and ‘>’ brackets inform the compiler to search for the file in this standard directory.

You can include an input-output stream header file with the following syntax.

#include <iostream>

or

#include "iostream"

Note: You can utilise any input output stream objects after including the header file <iostream> within your source code. This may include cin and cout. 

Here’s an example program that demonstrates the use of standard header files:

Example:

#include <iostream>
#include <vector>
#include <algorithm>
 
int main() 
{
std::vector<int> numbers = {2, 8, 5, 9, 4};
 
// The below command sorts the vector in descending order
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
 
// It will display the sorted vector
std::cout << "The sorted numbers in descending order are: ";
for (int num : numbers) 
{
    std::cout << num << " ";
}
std::cout << std::endl;
 
return 0;
}

 Output:

The sorted numbers in descending order are: 9 8 5 4 2 

The above program includes three header files. It then sorts the input numbers in descending order and displays the output using cout.

ii. User-defined header files

A program becomes difficult to read if it becomes too large. In such cases, it is recommended to divide it into tinier files and include them whenever required. Such files are known as user-defined header files. You can include such files as:

#include "filename"

where the double quotes ( ” ” ) inform the compiler to search for the corresponding header file in the source file’s directory.

3) Conditional Compilation

You can use conditional compilation directives in C/C++ to compile a specific portion of the program or to pass over the compilation of a specific portion of the program, depending on certain conditions. Here’s the list of preprocessor directives that helps you to insert conditional code:

#if Directive

#ifdef Directive

#ifndef Directive

#elif Directive

#else Directive

#endif Directive

The following syntax demonstrates the use of some of the conditional compilation directives in C/C++:

Syntax:

#ifdef macro_name
statement-1;
statement-2;
statement-3;
.
.
.
statement-N;
#endif

Here’s an example program that implements conditional compilation directives in C++.

#include <iostream>
#define MODE 1
 
int main() 
{
#if MODE == 1
    std::cout << "The mode is enabled" << std::endl;
#else
    std::cout << "The mode is disabled" << std::endl;
#endif
 
std::cout << "The program continues to execute" << std::endl;
 
return 0;
}

 Output:

The mode is enabled
The program continues to execute

The first step in the above program defines a macro MODE and assigns 1 to it. We use preprocessor directives in the main() function to conditionally compile various code blocks as per the value of MODE.

If MODE is declared as 1, the code block within #if MODE == 1 and #endif will be compiled. So, it prints the message "The mode is enabled" to the output console.

If MODE is defined with some other value or not being defined, then the code block written in the #else and #endif will be compiled. So, it prints the message "The mode is disabled".

Irrespective of the value of MODE, the line std::cout << "The program continues to execute" << std::endl; will be executed.

4) Other Directives

In addition to the above-discussed directives, two more directives exist, but they are not commonly used. They are:

#undef Directive

#pragma Directive

Let’s look at their details.

i. #undef Directive

It undefines an existing macro. Its syntax is:

#undef PI

It undefines the macro PI.

ii. #pragma Directive

They are special-purpose directives that are used to turn on or off certain features. They offer some extra information to the supported compilers when compiling a C/C++ Program. They are compiler specific.

The following section discusses a few of the #pragma directives.

#pragma startup: It allows you to declare the functions that are required to run before the program startup. It means you can use them to declare functions before the control passes to the main() function.

#pragma exit: It allows you to declare the functions that are required to run immediately before the program exit. You can use them for function declaration before the control returns from the main() function.

Here’s an example program that demonstrates #pragma startup.

void func1();
 
// declaring funct1 to execute at the start
#pragma startup func1
 
 
void func1() { printf("Inside func1()\n"); }
 
int main()
{
        void func1();
        printf("Inside main()\n");
 
        return 0;
}

 Output:

Inside main()

Note: The above program doesn’t work with GCC compilers.

As seen from the above program, #pragma startup func1 is used to declare void func1().

 Conclusion

Usually, C/C++ preprocessors commands are executed as the foremost step in the compilation of a program. These preprocessors make your C/C++ program easy to develop, easy to read, and easy to modify. Moreover, they make your code more transportable between various machine architectures.

Tutorials serve as one of the most effective ways to get acquainted with various aspects of C and C++. Along with going through the tutorials, pursuing upGrad’s Full Stack Software Development Bootcamp enables career advancement in the cutting-edge tech industry. It encompasses in-demand topics imparted by industry experts to make you stand out in the industry. Moreover, the extraordinary aspects like industry projects, Cloud Labs, career guidance sessions, performance reports, etc., ensures upGrad elevates your career growth in STEM!

FAQs

1. What is the usefulness of the #pragma warn directive in C?

The #pragma warn directive in C hides the warning message that is displayed during compilation. Using different #pragma commands, depending on the type of compiler you use, you can disable specific warning messages.

2. Where are preprocessor directives written in C/C++?

The preprocessor directives written in C/C++ are written in source code. We write preprocessor directives like macros definition and file inclusion outside the main() function at the top of a C/C++ program.

3. How is the bits/stdc++.h header file useful?

The bits/stdc++.h header file helps you to include all the standard library functions in C++. The syntax is #include <bits/stdc++.h>. You can make use of any standard library header files in your C program by incorporating this header file in your source code. This includes, <iostream>, <vector>, <cmath>, <algorithm>, etc.

4. What are the # and ## operators in C/C++/

The # and ## operators are preprocessor operators in C/C++. The # operator encloses the appropriate arguments passed in the corresponding macros in double quotation marks. Also, it transforms the input it precedes into a quoted string. The ## operator concatenates/merges the passed arguments or tokens to generate a new variable/token.

Leave a Reply

Your email address will not be published. Required fields are marked *