Skip to the content.

Макросы


Макросы - инструкции препроцессора (самостоятельный яп, который ничего не знает про синтаксис С++ и работает с кодом как с обычным текстом)

Используя макросы можно написать “подобие” функции:

#define max2(x,y) ((x) > (y) ? (x) : (y))
a = max2(c,d);
// при компиляции вместо max2(c,d) препроцессор подставит строку ((c) > (d) ? (c) : (d)).
// max2(x,y) что-то типо переменной, принимающей два параметра

Параметр макроса можно превратить в строку, добавив перед ним знак #:

#define MACRO(PARAM) "Macro received: " #PARAM
int x = 5;
std::cout << MACRO(x) << "\n"; // Macro received: x

Параметр макроса можно приклеить к чему-то еще, чтобы получить новый идентификатор, для этого нужно между ними поставить знак ##:

#define MACRO(PARAM) value_##PARAM
int value_x = 5;
std::cout << MACRO(x) << "\n"; // 5
// приклеит value_ к x и выведет соответственно значение value_x

❗ Параметры макросов и сам макрос лучше нужно оборачивать круглыми скобками:

#define max2(x,y) x > y ? x : y // <- не обернули скобками
a = b + max2(c,d); 
// превратится в a = b + c > d ? c : d, а это уже совсем другое условие

Но оборачивание скобками тоже не избавляет от всех проблем, например что будет, если мы передадим макросу с++ вместо c?

#define max2(x,y) ((x) > (y) ? (x) : (y))
a = b + max2(c++,d); 
// превратится в a = b + ((c++) > (d) ? (c++) : (d))
// каждый раз когда в условии будет встречатся с++, будет выполнятся инкремент
// а мы ожидали что инкремент выполнится один раз, и будет передано с+1

❗ В общем говоря использовать макросы вместо функций плохая практика, поскольку макросы очень трудно грамотно написать.

Зато макросы очень удобно использовать для условной компиляции:

#ifdef DEBUG
    // отладочная информация
#endif

Теперь для того что бы компилировать и вывести всю отладочную информацию достаточно вначале программы написать:

#define DEBUG

В ином случае все что между директивами условной компиляции будет стёрто на этапе препроцессинга и не попадёт в компилятор.

Снять определение:

#undef DEBUG