#define Conflicting with Conditionally #include-d Library



这里有一个简化的例子。假设我正在使用库B和C编写程序A。Niether库的源代码可以更改,并且它们是唯一可用的库。库B有一个合理的#define,而库C有一个别名为愚蠢的#define

//library_b_header.hpp
#pragma once
#define uint16 unsigned short
//...
//library_c_header.hpp
#pragma once
#define uint16 unsigned char

我的大多数先例都是这样的问题。有一个答案很有帮助,涵盖了我看到的一系列建议(转述):

  • 在您自己的代码中添加#undef
  • 不要直接包含library_c_header.hpp。如果其他库为您包含它,请不要直接包含。相反,将其包含在一个单独的.cpp文件中,然后可以在其标头中公开包装器函数
  • 重命名您自己的符号

第二个选项接近我的正常解决方案,但库C很大;我不可能包装所有的功能。即使我可以,也很有可能会出错,而且它肯定不能移植到C库的新版本(这也是经常发生的)。

第三个选项不起作用,因为它在任何地方都使用。与之冲突的不仅仅是;它与相冲突,实际上所有其他。我想这可以完成。这只是一个错误的#define,它应该死

这里的第一个选项最接近我正在尝试的。第二个问题是#include ing库C依赖于库B中定义的令牌。

我得到的最远的是:

#include <library_b/library_b_header.hpp>
#define library_b_uint16 uint16
#undef uint16
#ifdef LIBRARY_B_SYMBOL
    #include <library_c/library_c_header.hpp>
    #undef uint16
    #define uint16 library_b_uint16
#endif

这显然不起作用,但也许它表达了我的意图。还有什么我可以试试的吗?

如果您的编译器支持push_macropop_macro杂注,您可能可以这样使用它们:

#include <library_b/library_b_header.hpp>
#pragma push_macro("uint16")
#undef uint16
#include <library_c/library_c_header.hpp>
#pragma pop_macro("uint16")

(这些杂注是非标准的,但它们受到广泛支持。Visual C++、gcc、clang和"英特尔C++编译器"都支持它们。)

是的,您需要在包含库C中定义此宏的标头的任何位置执行此操作,但这通常可以通过编写自己的标头来简化,该标头封装库C标头的包含,然后在项目中需要库C的任何位置包含该标头。

最新更新