C++ Preprocessors and Macros

As the name suggests, C++ preprocessors are tools that transform (preprocess) our program before it is compiled.

Preprocessors use preprocessor directives in order to control the code transformation. For example,

#include <iostream>

Here, #include is a preprocessor directive that inserts the contents of the <iostream> header file into our program before compiling it.

Working of C++ preprocessor in the compilation process
Working of C++ preprocessor

Preprocessor Directives

In C++, all preprocessor directives begin with the # symbol. For example, #include, #define, #if, and so on.

Some of the common applications of C++ preprocessors are:

  • #include - to include header files
  • #define - to define macros
  • #if - to provide conditional compilation

Now, let's learn about each of these preprocessor directives in detail.


#include Preprocessor Directive

The #include directive is used to include header files in our program. For example,

#include <cmath>

Here, cmath is a header file. The #include directive tells the preprocessor to replace the above line of code with the contents of the cmath header file.

This is the reason we need to use #include <cmath> to use functions like pow() and sqrt().

We can also create our own custom header files and use them in our program using the #include directive. For example,

#include "path_to_file/my_header.h"

Here, we have included a custom header file named my_header.h in our program.

This way, we can divide a larger program into multiple files.


#define Preprocessor Directive

The #define directive is used to "define" preprocessor variables which can be used in our programs. For example,

#define PI 3.1415   // value of pi

Now, when we use PI in our program, it is replaced with 3.1415.

Here, PI is known as a macro. A macro is a fragment of code which has been given a name.


Example 1: C++ #define

Output

Enter the radius: 4
Area = 50.264

Function-like Macros

We can also use #define to create macros that work like a function. For example,

#define circleArea(r) (3.1415 * r * r)

Let's take a working example:

Output

Area = 19.6344

Here, the code circleArea(radius); expands to 3.1415 * 2.5 * 2.5.

Note: It is better to use functions rather than function-like macros as macros are more error-prone.


#if Preprocessor Directive

The #if directive is used to instruct the preprocessor whether to include a block of code or not depending on certain conditions.

It can also be used in conjunction with the #else and #elif directives in case of multiple conditions.

Hence, the #if, #else, and #elif directives are quite similar to if...else statements in C++ with one major difference.

The if...else statements are tested during execution time to check if the block of code should be executed or not.

On the other hand, conditional directives are tested by the preprocessor before compilation to decide whether to include a block of code in the program or not.

Here's a simple example,

Output

3 is greater than 0.

Here, the #endif directive is used to indicate the completion of the #if and #else directives.

However, if...else statements are preferred over preprocessor directives for deciding which part of the code to execute during runtime.

Nevertheless, there are a few situations where #if directives are more applicable:

  • To use different code depending on the operating system (platform-specific code).
  • To include debugging codes (like printing debugging messages) that are run only on debugging builds.
  • To toggle features on and off depending on certain conditions.
  • To include code that is specific to certain versions or releases of the software (version-specific code).

Example 2: Platform-Specific C++ Code

Output

Hello from Linux!

This is an example of platform-specific code using conditional compiling.

Here,

  • _WIN32 - a macro defined by the Microsoft Visual C++ compiler on Windows platforms
  • __linux__ - a macro defined by GNU C Compiler on Linux systems
  • #ifdef - a variant of #if which checks if a macro has been defined or not

The macros _WIN32 and __linux__ are used to determine the system on which the program is running.


Predefined Macros

Here are some commonly used predefined macros in C++ programming.

Macro Value
__DATE__ A string containing the current date.
__FILE__ A string containing the file name of the currently executing program.
__LINE__ An integer representing the current line number.
__TIME__ A string containing the current time (GMT).

Note: Since these are predefined macros, we do not need to use the #define directive to use them.


Example 3: Predefined Macros

Output

Current time: 04:23:31

This program prints the current time (GMT) using the __TIME__ macro.