保留预处理器定义
可能的重复:
我可以重新定义 C++ 宏然后重新定义它吗?
假设我有一些代码使用名称 BLAH
作为变量。假设 BLAH
是许多标准头文件(定义为 10)中常见的预处理器定义,因此如果我的文件包含在其中任何一个文件之后,代码就会中断,因为 BLAH
已被转换分成 10 个;因此,我必须#undef BLAH
。但其他标头也可能依赖于 BLAH
,因此我必须在标头完成后将 BLAH
恢复为其原始值。是否可以做这样的事情:
#ifdef BLAH
#define BLAH_OLD BLAH
#undef BLAH
#endif
... code ...
// restore BLAH to 10
#ifdef BLAH_OLD
#define BLAH BLAH_OLD
#end
?这当然不起作用,因为 BLAH 没有扩展到 10。我尝试过做类似的事情
#define EXPAND_AGAIN(x) x
#define EXPAND(x) EXPAND_AGAIN(x)
#define BLAH_OLD EXPAND(BLAH)
,但这也不起作用,因为 EXPAND 是字面意思而不是扩展。我使用的是 MSVC 2008/2010,但如果该解决方案也适用于大多数其他编译器,那就太好了。
Possible Duplicate:
Can I redefine a C++ macro then define it back?
Say I have some code that uses the name BLAH
for a variable. Suppose BLAH
is a common preprocessor definition in many standard header files (defined as 10), so if my file is included after any of them, the code breaks because BLAH
is transformed into 10; therefore, I must #undef BLAH
. But also other headers may depend on BLAH
, so I must restore BLAH
to it's original value after my header is done. Is it possible to do something like this:
#ifdef BLAH
#define BLAH_OLD BLAH
#undef BLAH
#endif
... code ...
// restore BLAH to 10
#ifdef BLAH_OLD
#define BLAH BLAH_OLD
#end
? This doesn't work of course, because BLAH is not expanded to 10. I have tried doing something like
#define EXPAND_AGAIN(x) x
#define EXPAND(x) EXPAND_AGAIN(x)
#define BLAH_OLD EXPAND(BLAH)
but that doesn't work either, since EXPAND is taken literally and not expanded. I am using MSVC 2008/2010, but it would be lovely if the solution would work on most other compilers too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,假设您的编译器支持 push/pop 宏指令(Visual C++、gcc、llvm 都支持):
Yes, given that your compiler supports the push/pop macro directives (visual c++, gcc, llvm all do):
不幸的是,预处理器不支持定义堆栈。
Boost 预处理器库使预处理器可以完成您从未想象过的事情(例如 C++98 中的有效可变参数宏),但受到预处理器固有限制的约束 - 所以,抱歉,无法做到。
唯一已知的中间补救措施是为宏保留
ALL_UPPERCASE_IDENTIFIERS
,并始终将它们用于宏。它在一定程度上减少了名称冲突问题。不幸的是,C 标准库定义了许多小写宏,或者允许它们的存在,例如assert
,但它们只是其中的几个。从实际角度来看,主要问题在于 Windows 编程,其中 Microsoft 的 [windows.h] 标头定义了无数个非大写宏,默认情况下包括
min
和max
与 C++ 标准库冲突。因此,对于 Windows C++ 编程,请始终在包含 [windows.h] 之前定义
NOMINMAX
。干杯&呵呵,
Unfortunately the preprocessor doesn't support a stack of definitions.
The Boost preprocessor library makes the preprocessor do things you'd never imagine it could do (like effectively variadic macros in C++98), but is bound by the inherent limitations of the preprocessor -- so, no can do, sorry.
The only known half-way remedy is to reserve
ALL_UPPERCASE_IDENTIFIERS
for macros, and consistently always use them for macros. It reduces the name collision problem somewhat. Unfortunately the C standard library defines a number of lowercase macros, or allows for their existence, like e.g.assert
, but they are just a few.From a practical point of view the main problem is in Windows programming, where Microsoft's [windows.h] header defines zillions of non-uppercase macros, including, by default,
min
andmax
which conflict with the C++ standard library.So, for Windows C++ programming, always define
NOMINMAX
before including [windows.h].Cheers & hth.,
我曾经相信你尝试过的同样的技巧确实有效,因为我自己曾经使用过它。但我最终发现它实际上根本不起作用。简单的答案是否定的,您不能保存定义的当前值,更改它,然后恢复旧值。预处理器根本不是这样工作的。一旦定义了新值,旧值就消失了。
I used to believe that the very same trick you tried does work, as I used to use it myself. But I eventually learned that it actually does not work at all. The simple answer is NO, you cannot save a define's current value, change it, and then restore the old value. The preprocessor simply does not work that way. Once you define a new value, the old value is gone.
对我有用的一个技巧是在类中使用枚举。
就可以使用
然后当你需要“10”时
。由于它是类的一部分,因此“blah”的其他用法不会发生冲突,并且您可以保存所有 def'ing 和 undef'ing。
One trick that works for me is to use an enum in the class.
Then you can just use
when you need '10'.
Since it's part of the class then other uses of 'blah' won't conflict and you save all that def'ing and undef'ing.