【问题标题】:Can I redefine a C++ macro then define it back?我可以重新定义一个 C++ 宏然后再定义它吗?
【发布时间】:2010-12-20 02:39:48
【问题描述】:

我在我的代码中同时使用了 JUCE 库和一些 Boost 标头。 Juce 将“T”定义为宏(groan),而 Boost 在其模板定义中经常使用“T”。结果是,如果您以某种方式在 Boost 标头之前包含 JUCE 标头,则预处理器会在 Boost 代码中扩展 JUCE 宏,然后编译器将无可救药地丢失。

在大多数情况下保持我的包含顺序正确并不难,但是当您有一个包含其他一些类的 JUCE 类并且在链的某个位置上的某个文件包含 Boost 时,它会变得很棘手,如果任何需要 JUCE 之前的文件包括你有麻烦。

我最初希望解决这个问题

#undef T

在任何包含 Boost 之前。但问题是,如果我不重新定义它,那么其他代码会因为没有声明“T”而感到困惑。

然后我想也许我可以像这样做一些循环的#define 诡计:

// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___

丑陋,但我认为它可能会起作用。

很遗憾,没有。我在使用“T”作为宏的地方出现错误

'___T___' was not declared in this scope.

有没有办法让这两个库可靠地协同工作?

【问题讨论】:

  • 你为什么将 T 定义为 T,然后立即取消定义 T(反之亦然)?
  • 我想我可以通过查找原始定义并重新定义来解决这个问题,但我宁愿有更通用和更可靠的东西。
  • Jim 我不确定格式是否让您的问题更难理解,但我认为我的问题很干净?你认为你可以改写你的问题吗?
  • 我认为这是不可能的。也许制作一个包装头来取消定义 T 并用不同的名称定义宏。

标签: c++ boost macros c-preprocessor


【解决方案1】:

正如 grayfade 指出的那样,您的 ___T___ 技巧不起作用,因为预处理器是一个非常简单的生物。另一种方法是使用 pragma 指令:

 // juice includes here
 #pragma push_macro("T")
 #undef T
 // include boost headers here
 #pragma pop_macro("T")

这应该可以在 MSVC++ 中使用,并且 GCC 添加了对 pop_macropush_macro 的支持以与其兼容。虽然从技术上讲它是依赖于实现的,但我认为没有一种标准的方法可以暂时禁止定义。

【讨论】:

  • 六年过去了,还是那么酷!我使用这种技术使 Win32 DLL 能够使用它自己的入口点之一,而无需创建模块定义文件!
【解决方案2】:

您能否将有问题的库包装在另一个包含中并将#define T 困在里面?

例如:

JUICE_wrapper.h:     
#include "juice.h"
#undef T

main.cpp:    
#include "JUICE_wrapper.h"    
#include "boost.h"

 rest of code....

【讨论】:

  • 我正要建议在每个#include "juice.h" 之后添加一个#undef T。这里的想法相同,但更干净。
  • MGB,实际上我最终按照您的建议进行了操作,但感觉彼得更准确地回答了所提出的问题。非常感谢您的建议。
  • 我正在寻找 push/pop 宏来检查它的确切作用,但我找不到它!结尾有“_macro”很愚蠢
【解决方案3】:

然后我想也许我可以像这样做一些循环的#define 诡计:

C 预处理器不能以这种方式工作。预处理器符号的定义与定义函数时赋予符号含义的含义不同。例如

将预处理器视为文本替换引擎可能会有所帮助。当一个符号被定义时,它被视为一个直接的文本替换,直到文件结束或直到它未定义。它的值不存储在任何地方,因此无法复制。因此,在 #undefed 之后恢复 T 的定义的唯一方法是稍后在代码中以新的 #define 完全重现其值。

您能做的最好的事情就是不使用 Boost 或请求 JUCE 的开发人员不要将 T 用作宏。 (或者,最坏的情况,通过更改宏名称自行修复。)

【讨论】:

    猜你喜欢
    • 2020-06-22
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 2020-04-20
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多