TGViewer
C++: Хроники Дурки🚑 C++: Хроники Дурки🚑 @cpp_durka · 916 subscribers
Post #23 1.1K
Иногда нам приходится использовать самое страшное и отвратительное что досталось С++ по наследству: препроцессор.

По разным причинам - или средствами языка нельзя что-то емко выразить (как в либах Unreal Engine), или для производительности (иногда голый код лучше оптимизируется чем функции, и макросы пишутся вместо функций под комментарием "счастливого дебага, тварь"), иногда просто по дурости (как в QT).

И там можно выстрелить себе в ногу самым неожиданным образом.

Вот простой макрос:


#define INCREMENT_BOTH(x, y) x++; y++


Что тут не так?
Да много чего.

Вот такой пример:


int a = 0; int b = 0;
INCREMENT_BOTH(a+b, b);


Вообще это преобразуется в


a+b++; b++;

И это явно не то, что мы хотели. Мы хотели тут ошибку компиляции на том, что "пытаемся инкрементить lvalue", а вместо этого простой ворнинг про "неиспользуемый результат".

Но это полбеды, тут даже идейно макрос использован неверно.

Какой-нибудь вот такой пример:


int main() {
int a = 0; int b = 0;

for (const auto f: {true, false}) {
if (f)
INCREMENT_BOTH(a, b);
}

std::cout << "a: " << a << "\n"
<< "b: " << b << "\n"
<< std::endl;

return 0;
}


Разумно выведет


Program returned: 0
a: 1
b: 2


а clang даже со включенным Wall не выдаст ни одного ворнинга.

И это далеко не все проблемы. Когда-то давно, когда мне надо было писать макросы, мне к задачам выдали 18-страничный гайд "как правильно писать макросы", согласно которому единственно верным способом написать такой макрос будет


#define INCREMENT_BOTH(x, y) \
do { \
(x)++; \
(y)++; \
} while (0)


Не используйте макросы без крайней необходимости. А если используете - найдите тот гайд, и пришлите его мне (я его потерял и очень об этом жалею 🙁 )
godbolt.org Compiler Explorer - C++ #define INCREMENT_BOTH(x, y) x++; y++ int main() { int a = 0; int b = 0; for (const auto f: {true, false}) { if (f) INCREMENT_BOTH(a, b); } std::cout << "a: " << a << "\n" << "b: " << b << "\n" …
  • ❤ 18
More from @cpp_durka
  1. Sep 8, 2026Мошенники заставили пенсионерку из Москвы переписать квартиру на Rust
  2. Aug 31, 2026Всяко разное болезненное есть в С++, из всего болезненного одно из самых болезненных - это…
  3. Aug 24, 2026Если кто не знаком с библиотекой nlohmann/json - она прекрасна. Мои мысли о том, как должн…
  4. Aug 21, 2026#толькосвоимемы Код взят тут. if (dim == 0) idx_dim = i0; else if (dim == 1) idx_dim = i1;…
  5. Aug 17, 2026Ладно, искать баги в компиляторах весело, но недостаточно. Давайте поиграемся в чуть более…
  6. Aug 10, 2026Ладно, разумеется прошлый пост был набросом. Никогда не обновляйте компиляторы без очень с…
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 →