One of the special aspects of C++ is preprocessor directives. It offers numerous facilities which other high-level languages can not, as well as programmers can utilize these tools to construct C ++ programs that are effective, simple to read, simple to edit, and portable.
The compiler processes the source code just before the compiler compiles a C++ program. Preprocessor is the name of the technique while preprocessing is the name of the operation. It is a kind of separate program section that is called by the C++ compiler in the very first part of the translation. This procedure falls inside the compilation process but is not a component of the compiler. It instructs the compiler to preprocess the data before beginning the compilation process.
Since this is not a statement in C++, all preprocessor directives in that language start with # and do not need to conclude with a semicolon (;).
A symbolic constant is created via the #define
directive, and these symbolic constants are usually referred to as macro.
The directive in its most general form is:
#define macro-name replacement-text
#include<iostream>
#define val 100
using namespace std;
int main()
{
cout << "Value will be :" << val << endl;
}
Output:
Value will be :100
Various preprocessor directives carry out various functions. These Preprocessor Directives fall under the following categories:
Inclusion Directives: | Macro Definition Directives: | Conditional Compilation Directives: | Other Directives |
---|---|---|---|
#include: defines the files that should be included, particularly header files. |
·#define: it mainly specifies a macro substitution.
·#undef:Undefining a macro is accomplished using it. |
·#if:It examines a compile-time condition.
·#endif:It indicates where #if ends.
·#ifdef:The macro definition is tested using this. ·#ifndef:If a macro is not defined, it is tested. ·#else:When #if fails, it offers an alternate choice. |
· #error: · #line:a line number is provided for compiler messages. ·#pragma:It gives the compiler instructions that are defined by the implementation. |
In a program, there are named sections of code called macros. When the compiler comes across this term, it switches out the name for the actual piece of code. A macro is defined using the '#define' directive. Let us use a program to understand the definition of a macro now:
#include <iostream>
// macro definition
#define LIMIT 6
int main()
{
for (int i = 0; i < LIMIT; i++) {
std::cout << i << "\n";
}
return 0;
}
Output:
0 1 2 3 4 5
When the compiler runs the preceding program, it substitutes the number 6 for the word LIMIT. In the macro definition, the word "LIMIT" is referred to as a macro template, while the number "6" is a macro expansion.
The macro definition ends without a semicolon (;). A semicolon is not required to finish macro definitions.
Macros with Arguments: Macros also accept arguments. Function-like behavior is shared by macros defined with arguments. Let's examine this using a program:
#include <iostream>
// macro with parameter
#define AREA(l, b) (l * b)
int main()
{
int l1 = 20, l2 = 10, area;
area = AREA(l1, l2);
std::cout << "The area of rectangle is: " << area;
return 0;
}
Output:
The area of rectangle is: 200
The program above demonstrates how the compiler substitutes the statement (l*b) whenever it encounters the expression AREA(l, b) in the program. Additionally, the values provided to the macro template AREA(l, b) in the statement (l*b) will be replaced. As a result, AREA(20, 10) will equal 20*10.
This kind of preprocessor directive instructs the compiler to add a file to the program's source code. The user can add two different sorts of files to the program:
Standard files versus header files: The pre-defined functions like printf()
, scanf()
, and others are defined in these files. For these functions to function, these files must be present. Various functions are declared in various header files. The 'iostream' file has functions that do basic I/O, whereas the'string' file contains functions that handle string operations.
Syntax:
#include< file_name >
where file name denotes the name of the file that should be included. The '<' and '>' brackets will tell the compiler to look in the standard directory for the file.
User-defined files: It's a good idea to break up a program into smaller files when it gets to be a size that makes it difficult to use it all at once. User-defined files are these kinds of files. You can include these files:
#include"filename"
Conditional compilation directives are a sort of directive that can be used to compile or omit to compile a specified section of a program depending on certain criteria. 'ifdef' and 'endif' are two preprocessing instructions that can be used to do this.
Syntax:
#ifdef macro_name
statement1;
statement2;
statement3;
.
.
.
statementN;
#endif
If a macro with the name "macro name" is defined, so the block of statements will execute ordinarily; however, if it is not declared, the compiler will skip this block of statements.
In addition to the two directives mentioned above, there are two others that are rarely used. Which are:
#undef Directive: A macro can be undefined by using the #undef directive. This command serves as:
#undef LIMIT
The existing macro LIMIT will be undefined if this statement is used. Following this one, all "#ifdef LIMIT" statements will evaluate to false.
#pragma Directive: This special purpose directive is intended to enable or disable certain functionality. These directives are compiler-specific, meaning they differ between compilers. The following are some of the #pragma directives:
GCC compilers are incompatible with the program below.
#include <bits/stdc++.h>
using namespace std;
void func1();
void func2();
#pragma startup func1
#pragma exit func2
void func1()
{
cout << "Inside the func1()\n";
}
void func2()
{
cout << "Inside the func2()\n";
}
int main()
{
void func1();
void func2();
cout << "Inside the main()\n";
return 0;
}
Output:
Inside the func1() Inside the main() Inside the func2()
When run by GCC compilers, the aforementioned code will result in the output seen below:
Inside the main()
This occurs as a result of GCC's lack of support for #pragma startup or exit.