Day 24.
Делам шаг на уровень 4.
Большинство компиляторов дают возможность использовать
__COUNTER__ (расширение компиляторов, не стандарт). В первый вызов он отдаёт 0, а далее значение на 1 больше.
Счётчик один внутри translation unit.
Если помните, мы генерировали уникальные имена для переменных с помощью LINE, но с ним проблема в том, что вы не можете объявить две переменные в одной строке, так как у обеих будет одно и то же имя. COUNTER решает эту проблему. Как его ни вызывай, он всё равно вверх растёт:
#define CONCAT_IMPL(a, b) a##b
#define CONCAT(a, b) CONCAT_IMPL(a, b)
#define UNIQUE_NAME(prefix) CONCAT(prefix, __COUNTER__)
int UNIQUE_NAME(x), UNIQUE_NAME(x);
Получим что-то вроде
int x0, x1;
Зачем нужны вообще эти уникальные имена? Например, для defer/finally/scope_exit:
#define SCOPE_EXIT(code) \
auto UNIQUE_NAME(_scope_) = make_scope_exit([&] { code; });
Вроде очевидно, но можно и такое сделать:
#define FOO(x) x + x
FOO(__COUNTER__); // 0 + 1
Всякими хитрыми трюками можно его «сбрасывать», но про это почекайте сами.
@thisnotes. Patreon, Boosty.
Спасибо Artyom Garkavy и niki4smirn.