Как вы выполняете расширение макроса в #ifdef?
У меня есть довольно общий код, который использует макросы препроцессора для добавления определенного префикса к другим макросам. Это очень упрощенный пример того, что происходит:
#define MY_VAR(x) prefix_##x
"prefix_" фактически определяется в другом месте, поэтому он будет отличаться каждый раз, когда файл будет включен. Это работает хорошо, но теперь у меня есть код, который я хотел бы пропустить, если один из токенов не существует, но это не работает:
#if defined MY_VAR(hello)
Я хочу, чтобы он расширился вот до чего:
#ifdef prefix_hello
Но я не могу понять ... как. Мне нужно использовать макрос MY_VAR() для расширения, поэтому я не могу просто жестко закодировать имя. (Это на самом деле для некоторого тестового кода, один и тот же код включается с разным префиксом каждый раз, чтобы протестировать кучу классов, и я хочу пропустить пару тестов для нескольких классов.)
Возможно ли это с препроцессором 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("%sn", MY_VAR(test));
#endif
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_
. (Неопределенные идентификаторы заменяются нулем.)
Я думаю, что вы дошли до того уровня, когда препроцессор больше не будет его резать; он действительно довольно простодушен. Вы рассматривали возможность использования шаблонов вместо этого? (При условии, конечно, что они значимы для вашей проблемы.)
Это ответ на ваш обновленный вопрос. Для каждого возможного 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 ..."бла-бла", добавить строку(ы):
static const char * const MY_VAR(test);
Для всех возможных значений MY_VAR и test. Это позволит избежать жесткого кодирования "hello_test". (Вторая константа здесь удаляет предупреждение gcc:’ hello_test ' определено, но не использованный.)