У меня есть разные переменные препроцессора, которые имеют разные имена в разных библиотеках.
Чтобы избежать конфликтов, я делаю следующее (в этом примере для простоты есть только 1 конфликтующая переменная и 1 заголовок):
#ifdef VAR
#define TEMPVAR VAR
#undef VAR
#endif
#include "conflictingheader.hh"
#ifdef VAR
#undef VAR
#endif
#ifdef TEMPVAR
#define VAR TEMPVAR
#undef TEMPVAR
#endif
Существует ли автоматический способ хранения всех конфликтующих переменных, их определения и последующего восстановления?
Или можно определить макрос для выполнения этих операций?
Язык C ++ не обеспечивает автоматизированный способ сохранения и восстановления макросов препроцессора. Макросы препроцессора (которые не определены в командной строке компилятора или компилятора) работают на глобальном уровне файла, и нет понятия ограничения области действия макроса конкретным заголовком, который используется #include
д.
Я бы решил такую проблему, создав новый заголовочный файл, который предоставляет интерфейсные оболочки для нужных мне функций из этой конкретной библиотеки, но без каких-либо макрозависимостей. Затем внедрите обертки в исходный файл, который включает только этот проблемный заголовочный файл.
Ваш компилятор может предоставить расширение, чтобы сделать задачу немного менее многословной, но не полностью автоматизированной, как я понимаю, вы понимаете.
Компиляторы GCC и Microsoft поддерживают макросы прагмы push и pop.
Для совместимости с компиляторами Microsoft Windows GCC поддерживает
#pragma push_macro("macro_name")
а также#pragma pop_macro("macro_name")
,
#pragma push_macro("macro_name")
Эта прагма сохраняет значение макроса с именемmacro_name
на вершину стека для этого макроса.
#pragma pop_macro("macro_name")
Эта прагма устанавливает значение макроса с именемmacro_name
к значению на вершине стека для этого макроса. Если стек дляmacro_name
пусто, значение макроса остается неизменным.
Нет стандартного способа сделать это. У @jxh отличный нестандартный способ. Причина, по которой это не работает, заключается в том, что макросы не оцениваются вообще, пока они не развернуты, они не оцениваются при использовании в другом определении макроса.
#define MY_MACRO VAR
#define MY_STR_MACRO2(M) # M
#define MY_STR_MACRO(M) "MY_MACRO = " MY_STR_MACRO2(M) "\n"
printf(MY_STR_MACRO(MY_MACRO)); //writes "VAR"
#define VAR 4
printf(MY_STR_MACRO(MY_MACRO)); //writes "4"
#undef VAR
printf(MY_STR_MACRO(MY_MACRO)); //writes "VAR" again
На каждой printf
линия, это смотрит на MY_MACRO
и видит, что это «VAR», а затем смотрит, если VAR
определяется ни к чему. Иногда это так, иногда нет.
Итак, когда вы попробуете это:
#define TEMPVAR VAR
Единственное, что запечатлено в TEMPVAR
такое «VAR» VAR
может оценить, что не рассматривается на данный момент и не будет, пока он не должен оценить TEMPVAR
,