C++. Conditional compilation. Directives #if, #else, #elif, #endif, #ifdef, #ifndef. The defined operator

Conditional compilation. Directives #if, #else, #elif, #endif, #ifdef, #ifndef. The defined operator


Contents


1. Directives #if, #else, #elif, #endif. Conditional compilation
1.1. Combination of #if – #endif directives

Using the directives #if, #else, #elif, #endif, you can specify parts of the program that need to be compiled depending on the value of the constant expression.

The general form of the #if directive is as follows

#if consant_expression
  operators_sequence
#endif

here

  • constant_expression – constant expression returning true or false;
  • operators_sequence – sequence of operators executed if constant expression=true.

Example.

#include <iostream>
using namespace std;

// Solution number
#define N_SOLUTION 2

// Number Pi
#define Pi 3.1415926535

// If the solution is 1, then calculate the circumference
#if N_SOLUTION == 1
#define RESULT(radius) 2*Pi*radius
#endif

// If the solution is 2, then calculate the area of the circle
#if N_SOLUTION == 2
#define RESULT(radius) Pi*radius*radius
#endif

void main()
{
  // 1. Radius
  double r;

  // 2. Enter the radius of the circle
  cout << "r = ";
  cin >> r;

  // 3. Calculate the area of a circle
  double area = RESULT(r);
  cout << "area = " << area << endl;
}

Program result

r = 3
area = 28.2743

 

1.2. Combination of directives #if – #else – #endif

The directives #if – #else – #endif allow you to compile one of two parts of the program depending on the value of the conditional expression. The general form of using this directive is as follows:

#if consant_expression
  operators_sequence_1
#else
  operators_sequence_2
#endif

here

  • constant_expression – expression that returns a value of a boolean type (true or false);
  • operators_sequence_1 – sequence of operators to be executed if constant_expression=true;
  • operators_sequence_2 – operator sequence to be executed if constant_expression=false.

Example.

In the example, depending on the value of N_SOLUTION, the necessary code fragment is compiled that determines the circumference or area of the circle.

#include <iostream>
using namespace std;

// Solution number
#define N_SOLUTION 1

// Number Пі
#define Pi 3.1415926535

// If the solution is 1, then a fragment is compiled that calculates the circumference,
// otherwise, a fragment is compiled that calculates the area of a circle.
#if N_SOLUTION == 1
#define RESULT(radius) 2*Pi*radius
#else
#define RESULT(radius) Pi*radius*radius
#endif

void main()
{
  // 1. Radius
  double r;

  // 2. Enter the radius of the circle
  cout << "r = ";
  cin >> r;

  // 3. Calculation
  double result = RESULT(r);
  cout << "result = " << result << endl;
}

Result

r = 3
result = 18.8496

 

1.3. Combination of directives #if – #elif – #endif. Chain if-else-if

The combination of #if-#elif-#endif directives forms the so-called if-else-if chain or the stepped (cascading) form of the #if directive. The #elif directive stands for else-if. With this form of directives, you can check many conditions. The general form of the #if-#elif-#endif directive is as follows

#if expression_1
  operators_sequence_1
#elif expression_2
  operators_sequence_2
  ...
#elif expression_N
  operators_sequence_N
#endif

where

  • expression_1, expression_2, expression_N – some expression that can be true or not true (false);
  • operators_sequence_1, operators_sequence_2, operators_sequence_N – sequence of operators to be compiled in the corresponding code block.

Example.

In the example, depending on the value of N_SOLUTION, the corresponding formula is calculated

#include <iostream>
using namespace std;

// Solution number
#define N_SOLUTION 3

// Число Пі
#define Pi 3.1415926535

// The fragment that corresponds to the solution number is compiled.
#if N_SOLUTION == 1
#define RESULT(radius) 2*Pi*radius // circumference
#elif N_SOLUTION == 2
#define RESULT(radius) Pi*radius*radius // the area of a circle
#elif N_SOLUTION == 3
#define RESULT(radius) 4.0/3*Pi*radius*radius*radius // the volume of a sphere
#endif

void main()
{
  // 1. Radius
  double r;

  // 2. Input radius
  cout << "r = ";
  cin >> r;

  // 3. Calculation
  double result = RESULT(r);
  cout << "result = " << result << endl;
}

Result

r = 3
result = 113.097

 

2. Directives #ifdef, #ifndef. Conditional compilation

The #ifdef and #ifndef directives provide another kind of conditional compilation. Literally, the meaning of directives can be defined as follows: “if defined”, “if not defined”.

The general form of #ifdef directives:

#ifdef macros_name
  operators_sequence
#endif

where

  • macros_name is the name of the macro, which is checked to see if it is defined by the #define statement. If a macro name is defined, the operators_sequence is executed;
  • operators_sequence – some sequence.

The general form of the #ifndef directive:

#ifndef macros_name
  operators_sequence
#endif

where

  • macros_name – macro name, which may or may not be defined. If the macro name is defined with the #define directive, then the operator_sequence is not executed;
  • operators_sequence – sequence of operators.

Example.

#include <iostream>
using namespace std;

#define Is_Calc_Length // Is it necessary to define the Length macro?

// If you want to define a macro that calculates the distance
// between two points, then define it
#ifdef Is_Calc_Length
#define Length(x1, y1, x2, y2) sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
#endif

// If you do not need to define the macro Length, then return 0
#ifndef Is_Calc_Length
#define Length(x1, y1, x2, y2) 0
#endif

void main()
{
  double x1, y1, x2, y2;
  cout << "x1 = "; cin >> x1;
  cout << "y1 = "; cin >> y1;
  cout << "x2 = "; cin >> x2;
  cout << "y2 = "; cin >> y2;

  double len = Length(x1, y1, x2, y2);
  cout << "len = " << len << endl;
}

Result

x1 = 1
y1 = 2
x2 = 3
y2 = 5
len = 3.60555

 

3. The defined operator. Determines whether a macro exists in the program

The defined statement is used in conjunction with the #if directive. The combination of these two elements replaces the #ifdef directive. The general form of using the defined operator is

defined macros_name

where

  • macros_name – macro name, which is checked for presence.

Example.

The example demonstrates an original way of solving a quadratic equation based on predefined formulas.

#include <iostream>
using namespace std;

// The defined operator.
// Formulas for calculating a quadratic equation.
#define D(a, b, c) (b*b - 4*a*c)
#define X1(a, b, c) ((-b - sqrt(D(a,b,c))) / (2*a))
#define X2(a, b, c) ((-b + sqrt(D(a,b,c))) / (2*a))

void main()
{
  // Calculation of quadratic equation.
  // Checking if there are formulas for calculating a quadratic equation.
#if defined D
#if defined X1
#if defined X2

  // 1. Declaring variables
  double a, b, c;

  // 2. Input coefficients
  cout << "a = "; cin >> a;
  cout << "b = "; cin >> b;
  cout << "c = "; cin >> c;

  // 3. Check if the equation exists
  if (a == 0)
  {
    cout << "Incorrect value of a (a==0)." << endl;
    return;
  }

  // 4. If the discriminant is greater than or equal to 0, then calculate
  if (D(a, b, c) >= 0)
  {
    cout << "x1 = " << X1(a, b, c) << endl;
    cout << "x2 = " << X2(a, b, c) << endl;
  }
  else
    cout << "The equation has no roots." << endl;

#endif
#endif
#endif
}

Result

a = -3
b = -4
c = 5
x1 = 0.7863
x2 = -2.11963

 


Related topics