Как Вы выполняете макрорасширение в #ifdef?

У меня есть некоторый довольно общий код, который использует макросы препроцессора для добавления определенного префикса на другие макросы. Это - очень упрощенный пример того, что происходит:

#define MY_VAR(x) prefix_##x

"префикс _" на самом деле определяется в другом месте, таким образом, это будет отличаться каждый раз, когда файл включен. Это работает хорошо, но теперь у меня есть некоторый код, который я хотел бы пропустить, если один из маркеров не существует, но это не работает:

#if defined MY_VAR(hello)

То, до чего я хочу, чтобы это расширилось, является этим:

#ifdef prefix_hello

Но я не могу выяснить как. Я должен использовать MY_VAR () макрос, чтобы сделать расширение, таким образом, я не могу просто hardcode имя. (Это на самом деле для некоторого кода тестирования, тот же код включен с другим префиксом каждый раз для тестирования набора классов, и я хочу пропустить несколько тестов для горстки классы.)

Действительно ли это возможно с препроцессором C++?

Обновление:

Вот некоторый полукомпилируемый код для демонстрации проблемы далее: (чтобы не хлюпать он в комментарии ниже)

#define PREFIX hello

#define DO_COMBINE(p, x)  p ## _ ## x
#define COMBINE(p, x)     DO_COMBINE(p, x)
#define MY_VAR(x)         COMBINE(PREFIX, x)

// MY_VAR(test) should evaluate to hello_test

#define hello_test "blah blah"

// This doesn't work
#ifdef MY_VAR(test)
  printf("%s\n", MY_VAR(test));
#endif
6
задан Brian Tompsett - 汤莱恩 24 February 2016 в 10:58
поделиться

3 ответа

Есть ли в вашей программе что-то большее, чем описывает этот вопрос? Директива

#define MY_VAR(x) prefix_##x

определяет ровно один идентификатор препроцессора. Вызов

blah ^&* blah MY_VAR(hello) bleh <>? bleh

просто поступает на один конец препроцессора и выходит на другой, ничего не определяя.

Без какой-либо другой магии вы не можете ожидать, что препроцессор запомнит, какие аргументы были переданы в какие макросы в ходе предыдущего исходного кода.

Вы можете сделать что-то вроде

#define prefix_test 1
#if MY_VAR(test) == 1
#undef prefix_test // optional, "be clean"
...
#endif
#undef prefix_test

, чтобы узнать, имеет ли префикс в настоящее время конкретное значение prefix_ . (Неопределенные идентификаторы заменяются нулем.)

3
ответ дан 17 December 2019 в 04:44
поделиться

Я думаю, что вы дошли до уровня, когда препроцессор больше не будет его сокращать; это действительно довольно простодушный. Рассматривали ли вы возможность использования шаблонов вместо этого? (Предполагая, что они имеют значение для вашей проблемы, конечно.)

2
ответ дан 17 December 2019 в 04:44
поделиться

Это ответ на ваш обновленный вопрос. Для каждого возможного hello_test, после любой возможности #define hello_test «бла-бла» добавьте строки:

#ifndef hello_test
#define hello_test (char*)0
#endif

Затем измените свой тест на:

if (MY_VAR(test))
    printf("%s\n", MY_VAR(test));

Или, в качестве альтернативы, перед все #define ... "blah blah", добавьте строку (и):

static const char * const MY_VAR(test);

для всех возможных значений MY_VAR и проверьте. Это позволит избежать жесткого кодирования hello_test. (Вторая константа здесь удаляет предупреждение gcc: 'hello_test' определено, но не используется.)

0
ответ дан 17 December 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: