Что такое макросы в C/C++?

«Что такое макросы в C/C++?» — вопрос из категории C++ Core, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Макросы — это директивы препроцессора, выполняющие текстовую подстановку в исходном коде до начала компиляции. Определяются с помощью #define.

Типы макросов:

  1. Макросы-объекты: Простая замена идентификатора на фрагмент кода.
    #define BUFFER_SIZE 1024
    char buffer[BUFFER_SIZE]; // Препроцессор заменит на char buffer[1024];
  2. Функциональные макросы: Макросы с параметрами.
    #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'ов. Для всего остального существуют более безопасные языковые средства.