Фон:
Позвольте предполагают, что у меня есть два заголовочных файла a.h и b.h.
a.h содержит:
#define VAR 1
b.h содержит:
#define VAR 2
Примечание: Название обоих из макроса - то же. Позвольте говорят, что у меня есть некоторый файл myFile.c, который включает оба из заголовочных файлов т.е. a.h и b.h.
Когда я пытаюсь получить доступ к VAR, я получаю ошибку переопределения VAR.
Для разрешения этой проблемы я вставил #ifndef оператор VAR и в a.h и в b.h файлы для предотвращения этой ошибки. файл a.h становится
#ifndef VAR
#define VAR 1
#endif
файл b.h становится
#ifndef VAR
#define VAR 2
#endif
Примечание: Заголовочный файл может содержать несколько макросы, не всего один макрос.
Проблема:
Давайте предположим, что a.h и b.h файлы получены из сторонней библиотеки. Эти файлы не содержат #ifndef оператор VAR.
Мне не разрешают изменить их заголовочные файлы.
Я могу разрешить макро-ошибку переопределения 'VAR' в myFile.c или myFile.cpp файле, который использует макрос VAR?
Я знаю меня, #undef VAR может использоваться для неопределения макро-VAR. Как я могу выборочно включать VAR позже в мою программу? т.е. на строке, которую кодируют 10 из myFile.c, я должен смочь обратиться к определению VAR из a.h файла, на строке 15 из моего кода я должен смочь обратиться к VAR из b.h файла, и на строке 18 снова я должен смочь обратиться к VAR из a.h файла.
Короче говоря, могут я, чтобы сделать макро-полиморфизм? Данный название заголовочного файла, это должно относиться к макроопределению, существующему в том файле.
Я думал об использовании приема пространства имен для решения вопроса. Определите первый заголовочный файл в пространстве имен первый и второй заголовочный файл во втором пространстве имен.
Я пытался определить два пространства имен. Первое пространство имен содержит #include a.h, и второе пространство имен содержит b.h. Однако прием пространства имен не работает с макросом. Когда я пытался получить доступ к firstns:: VAR, компилятор сообщает о сообщении об ошибке.
Можно ли предложить некоторый путь?
Вы можете всегда включать проблемные файлы заголовков через свой собственный выделенный заголовок. файлы, в которые можно добавить необходимые макросы #ifdef
, #undef
и т. д. для предотвращения ошибок переопределения. Например.
wrapperToA.h
-----
#ifdef VAR
#undef VAR
#endif
#include "a.h"
Обновление: @Vlad тем временем разработал полное решение - слава ему (и +1: -)
Продолжить ответ Питера Торока.
Обычно рекомендуется оборачивать сторонние компоненты.
Есть несколько шагов:
Вас больше интересует первое утверждение, которое также является наиболее распространенным. Просто оберните их:
// wrapper/a.h
#ifdef VAR
#undef VAR
#endif // ifdef VAR
#include <3rdparty/a.h>
Если вы систематически обертываете все свои зависимости таким образом, у вас не возникнет проблем с настройкой впоследствии, поскольку вы можете изменить свои собственные заголовки оболочки и просто перекомпилировать приложение, не вмешиваясь явно в сторонние заголовки (что является НИКОГДА не рекомендуется).
Однако есть вопрос о влиянии, который вы должны внимательно изучить ...
// 3rdparty/a.h
#define VAR 1
// 3rdparty/aa.h
#include "a.h"
typedef int IntArray[VAR];
// 3rdparty2/b.h
#define VAR 2
Это определенно сложнее :) Вам также необходимо заключить "aa.h" в undef
, чтобы избежать проблема ...
И, конечно, это означает, что вам лучше не полагаться на VAR
самостоятельно где-либо в вашем коде, поскольку вы знаете, что его определение может измениться в зависимости от порядка, в котором вы включаете заголовки .. .
Расширение макроса происходит на уровне препроцессора и не зависит от использования пространства имен.
Являются ли все макросы, которые вы хотите использовать, простыми константами, не используемыми в конкатенации токенов и т.д.?
Если да, то вы можете попробовать что-то вроде следующего, чтобы преодолеть разрыв между препроцессором и компилятором и сохранить доступ к A
и B
определениям VAR
и т.д., если это подходит для вашей ситуации:
// ab_wrapper.h
#include <a.h>
static const int A_VAR1 = VAR1;
static const char* A_VAR2 = VAR2;
#undef VAR1
#undef VAR2
#include <b.h>
static const int B_VAR1 = VAR1;
static const char* B_VAR2 = VAR2;
// code.c
#include <ab_wrapper.h>
...
int x = A_VAR1;
int y = B_VAR1;
...