处理宏重新定义而不修改.h文件… C / C ++语言

背景:

假设我有两个头文件啊和bh

啊包含:

#define VAR 1 

bh包含:

 #define VAR 2 

注意:两个宏的名称相同。 假设我有一些文件myFile.c,其中包含两个头文件ieah和bh

当我尝试访问VAR时,我得到VAR的重定义错误。

为了解决这个问题,我在ah和bh文件中插入了#ifndef VAR语句以防止出现此错误。 啊文件变成了

 #ifndef VAR #define VAR 1 #endif 

bh文件变成了

 #ifndef VAR #define VAR 2 #endif 

注意:头文件可以包含多个宏,而不仅仅是一个宏。

问题:

我们假设啊和bh文件是从第三方库获得的。 这些文件不包含#ifndef VAR语句。

我不允许更改其头文件。

我可以在使用VAR宏的myFile.c或myFile.cpp文件中解决宏’VAR’重定义错误吗?

我知道我#undef VAR可以用来取消定义宏VAR。 我怎样才能在我的程序中选择性地包含VAR? 即在myFile.c代码的第10行我应该能够从ah文件中引用VAR定义,在我的代码的第15行我应该能够从bh文件引用VAR并再次在第18行引用我应该能够引用来自啊文件的VAR。

总之,我能做宏多态吗? 给定头文件的名称,它应该引用该文件中存在的宏定义。

我想过使用命名空间技巧来解决问题。 在名称空间中定义第一个头文件,在名称空间中定义第二个头文件。

我尝试定义两个名称空间。 第一个命名空间包含#include啊,第二个命名空间包含bh但是,命名空间技巧不适用于宏。 当我尝试访问firstns :: VAR时,编译器会报告错误消息。

你能建议一些方法吗?

宏扩展发生在预处理器级别,并且不受命名空间使用的影响。

是否所有宏都要使用简单常量,而不是在标记串联等中使用?

如果是这样,那么您可以尝试类似以下内容来桥接预处理器/编译器间隙并保留对VAR等的AB定义的访问,如果它适合您的情况:

 // ab_wrapper.h #include  static const int A_VAR1 = VAR1; static const char* A_VAR2 = VAR2; #undef VAR1 #undef VAR2 #include  static const int B_VAR1 = VAR1; static const char* B_VAR2 = VAR2; // code.c #include  ... int x = A_VAR1; int y = B_VAR1; ... 

您可以始终通过自己的专用头文件包含有问题的头文件,您可以在其中添加必要的#ifdef#ifdef #undef等宏以防止重新定义错误。 例如

 wrapperToA.h ----- #ifdef VAR #undef VAR #endif #include "ah" 

更新: @Vlad在此期间制定了完整的解决方案 – 对他的赞誉(和+1 🙂

延伸Peter Torok的回答。

包装第三方组件通常是个好主意。

有多个步骤:

  • 将标题包装在您自己的标题中,这允许控制选项(例如,定义一些预处理标记或根据您自己的标记取消定义其他标记)
  • 创建一个轻量级的外观库,注意隐藏潜在危险的方法,必要时用互斥体包装它们等等……否则只需隐藏细节,以便任何更改都不会影响所有代码库。

您对第一个语句更感兴趣,这也是最常见的语句。 包装它们:

 // wrapper/ah #ifdef VAR #undef VAR #endif // ifdef VAR #include <3rdparty/ah> 

如果系统地以这种方式包装所有依赖项,那么之后调整就不会有任何问题,因为您可以修改自己的包装器头并重新编译应用程序而无需明确干预第三方标题(这是绝对不推荐的)。

然而,有一个问题,你应该仔细审查……

 // 3rdparty/ah #define VAR 1 // 3rdparty/aa.h #include "ah" typedef int IntArray[VAR]; // 3rdparty2/bh #define VAR 2 

这肯定更复杂:)你还需要用undef包装“aa.h”以避免问题…

当然,这意味着您最好不要在代码中的任何地方依赖VAR ,因为您知道它的定义可能会根据您包含标题的顺序而改变…