У меня есть некоторый довольно общий код, который использует макросы препроцессора для добавления определенного префикса на другие макросы. Это - очень упрощенный пример того, что происходит:
#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
Есть ли в вашей программе что-то большее, чем описывает этот вопрос? Директива
#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 ... "blah blah", добавьте строку (и):
static const char * const MY_VAR(test);
для всех возможных значений MY_VAR и проверьте. Это позволит избежать жесткого кодирования hello_test. (Вторая константа здесь удаляет предупреждение gcc: 'hello_test' определено, но не используется.)