Подход, который я выбрал бы, состоит в том, чтобы извлечь из каждого из включаемых файлов расширенную версию включаемых файлов, которая предоставит MYINT
через другой механизм вне самих включаемых файлов.
Итак, создайте включаемый файл из lib1.h
с именем lib1_ext.h
, содержащий следующие строки:
#if !defined(MYLIB1_EXT_H_INCLUDED)
#define MYLIB1_EXT_H_INCLUDED
// ensure that MYINT is not defined no matter what order the include files are used
#undef MYINT
#include "lib1.h"
const int myInt_lib1 = MYINT; // make a copy of the value of MYINT if it is needed
// make sure MYINT is undefined to allow the compiler to catch any dependencies on it
#undef MYINT
#endif
и аналогично для lib2.h
создать lib2_ext.h
как в:
#if !defined(MYLIB2_EXT_H_INCLUDED)
#define MYLIB2_EXT_H_INCLUDED
// ensure that MYINT is not defined no matter what order the include files are used
#undef MYINT
#include "lib2.h"
const int myInt_lib2 = MYINT; // make a copy of the value of MYINT if it is needed
// make sure MYINT is undefined to allow the compiler to catch any dependencies on it
#undef MYINT
#endif
теперь при использовании любой из функций библиотеки используйте соответствующую копию значения MYINT
, myInt_lib1
при использовании функции lib1.h
и / или myInt_lib2
при использовании функции lib2.h
. Однако, если MYINT
используется только с самим файлом заголовка библиотеки и нигде не нужен для фактического использования библиотеки, тогда вы можете просто отказаться от этого оператора.
См. Также Можно ли переопределить макрос C ++, а затем определить его обратно? , который показывает, как сохранить и восстановить определение макроса с помощью компиляторов некоторых поставщиков и директивы pragma
. Это не похоже на то, что это действительно применимо к вашей публикации.
Эта публикация также содержит ответ, который описывает основы расширения макросов и почему const int myInt_lib1 = MYINT;
необходим для сохранения значения MYINT
вместо использования препроцессора, как в #define MYINT_LIB1 MYINT
, для сохранения значения MYINT
, Препроцессор задерживает расширение макроса как можно дольше, и в результате попытка использовать макрос препроцессора, как в #define MYINT_LIB1 MYINT
для сохранения значения MYINT
, не работает, если MYINT
не определено с помощью #undef
директива. Когда препроцессор сначала заменяет текст MYINT_LIB1
на текст MYINT
, а затем выполняет повторное сканирование, поскольку MYINT
теперь не определено, текст MYINT
остается, и в случае неудачи получается ошибка компилятора.
Одна вещь, которую следует рассмотреть с этой работой вокруг
Это обходное решение предполагает, что все, что нужно, это числовое значение MYINT
, которое обрабатывается как постоянное значение int
. Таким образом, предполагается, что места, где используется MYINT
, - это места, где также можно использовать const int
.
Это означает, что любой вид вставки токена, #if
test или другое действие препроцессора, которое включает обработку текста, который MYINT
определен как текст, который может использоваться препроцессором для других макроопераций, не будет работать должным образом за пределами мест, где lib.h
или lib2.h
включены и обработаны препроцессором.
Это также означает, что вы не можете указать опцию компилятора, чтобы объявить MYINT
как часть условной компиляции, так как макрос, созданный опцией компилятора, будет игнорироваться и удаляться при этом обходе.
Таким образом, любая зависимость, которую источник, сгенерированный Препроцессором, имеет в MYINT
как текстовый макрос вне каждого из включаемых файлов, приведет к сбою компиляции.
Примером возможной зависимости может быть макрос внутри lib1.h
, который использует MYINT
для создания дополнительного невидимого аргумента функции, как в:
int funcStuff (int a, struct b *pBthing);
#define FUNCSTUFF (pBthing) funcStuff(MYINT, (pBthing))
с ожиданием, что любой, кто использует библиотеку, будет использовать FUNCSTUFF(&bThing);
вместо funcStuff (MYINT, &bThing);
. Чтобы это работало, вам нужно либо использовать функцию funcStuff()
напрямую, как в funcStuff(myInt_lib1, &bThing);
, либо создать собственную версию макроса FUNCSTUFF()
, использующего myInt_lib1
вместо MYINT
.
.