TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #681 5.73K
Макросы
#новичкам

Один из способов избежать дублирования кода — использовать макросы. Макросы — инструкции препроцессора, которые позволяют заменять одни строки на другие:

#define MAX(a, b) ((a) > (b) ? (a) : (b))


Теперь вы можете использовать этот макрос, возвращающий максимальное из 2-х значений, для любых типов данных:

int result1 = MAX(1, 2);          // Работает
double result2 = MAX(1.5, 2.5); // Тоже работает


Но использование макросов — это игра в русскую рулетку. Никогда не знаешь, когда в голове появится на 2 дырки больше. Они работают на уровне текстовой подстановки, и если что-то пойдет не так, компилятор вам не поможет. Как вы думаете, какие значения будут у переменных result, x и y после выполнения следующего кода?

#define MAX(a, b) ((a) > (b) ? (a) : (b))

int x = 5;
int y = 10;

int result = MAX(++x, ++y);


Мы хотим сравнить две переменные после их инкрементов. Поэтому ожидаемые значения: 11, 6, 11. Однако у препроцессора и компилятора есть свое мнение на этот счет. Реальный вывод:

Result: 12
x: 6
y: 12


Переменная y имеет значение на один больше ожидаемого. Это перестает быть удивительным после того, как мы посмотрим на то, во что раскрывается макрос:

int result = ++x > ++y ? ++x : ++y;


Мы просто подставили текст и в любых значениях x и y, одна из этих переменных претерпит лишний инкремент.

Более сложные ситуации генерируют все менее и менее тривиальные ошибки.

Недостатки макросов

🔞 Нетипобезопасность: Макросы не проверяют типы данных. Программа может скомпилироваться, но упасть в runtime.

🔞 Побочные эффекты: Макросы могут привести к неожиданным результатам, особенно если аргументы содержат побочные эффекты (например, инкременты).

🔞 Сложность отладки: Макросы могут раскрываться в причудливые строки, которые вы просто не увидите в своем коде. Придется отлаживаться по файлу с кодом после препроцессора, а это нетривиальная задача.

Макросы — это как использовать переводчик текста по изображению. В идеальных случаях работает хорошо, но иногда может "кабачок" интерпретировать как "маленький дешевый ресторан".

Поэтому CppCoreGuideLines говорят нам не использовать макросы при определении функций.

Вместо макросов в С++ есть шаблоны и вычисления времени компиляции, возможности которых с каждым стандартом все возрастают.

Don't be confusing. Stay cool.

#cppcore
  • 👍 33
  • 😁 11
  • ❤ 4
  • 🔥 3
  • ❤‍🔥 1
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →