Ответ
Макросы — это директивы препроцессора, выполняющие текстовую подстановку в исходном коде до начала компиляции. Определяются с помощью #define.
Типы макросов:
- Макросы-объекты: Простая замена идентификатора на фрагмент кода.
#define BUFFER_SIZE 1024 char buffer[BUFFER_SIZE]; // Препроцессор заменит на char buffer[1024]; - Функциональные макросы: Макросы с параметрами.
#define MAX(a, b) ((a) > (b) ? (a) : (b)) int x = MAX(10, 20); // Заменится на ((10) > (20) ? (10) : (20))
Критические проблемы макросов:
- Отсутствие типизации и проверки области видимости.
- Побочные эффекты: Из-за множественной подстановки аргументы могут вычисляться несколько раз.
#define SQUARE(x) ((x) * (x)) int a = 5; int bad = SQUARE(++a); // Разворачивается в ((++a) * (++a)) -> Неопределенное поведение! - Сложность отладки: Компилятор и отладчик видят код уже после подстановки.
Современные альтернативы в C++:
- Для констант:
const/constexpr.constexpr size_t BufferSize = 1024; // Типобезопасно, вычисляется на этапе компиляции. - Для функций: Встраиваемые функции (
inline), шаблоны,constexpr-функции.template<typename T> inline T max(T a, T b) { return a > b ? a : b; } // Типобезопасно, нет побочных эффектов.
Вывод: В C++ макросы следует использовать с крайней осторожностью, в основном для условной компиляции (#ifdef DEBUG) или include guard'ов. Для всего остального существуют более безопасные языковые средства.