Избегайте переопределения переменной препроцессора

У меня есть разные переменные препроцессора, которые имеют разные имена в разных библиотеках.

Чтобы избежать конфликтов, я делаю следующее (в этом примере для простоты есть только 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

Существует ли автоматический способ хранения всех конфликтующих переменных, их определения и последующего восстановления?

Или можно определить макрос для выполнения этих операций?

5

Решение

Язык 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 пусто, значение макроса остается неизменным.

Документация GCC

8

Другие решения

Нет стандартного способа сделать это. У @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,

0

По вопросам рекламы [email protected]