保留预处理器定义

发布于 2024-10-01 05:01:23 字数 867 浏览 4 评论 0原文

可能的重复:
我可以重新定义 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

秋凉 2024-10-08 05:01:23

是的,假设您的编译器支持 push/pop 宏指令(Visual C++、gcc、llvm 都支持):

#define BLAH 10

#pragma push_macro("BLAH")
#undef BLAH

#define BLAH 5

...

#pragma pop_macro("BLAH")

Yes, given that your compiler supports the push/pop macro directives (visual c++, gcc, llvm all do):

#define BLAH 10

#pragma push_macro("BLAH")
#undef BLAH

#define BLAH 5

...

#pragma pop_macro("BLAH")
じ违心 2024-10-08 05:01:23

不幸的是,预处理器不支持定义堆栈。

Boost 预处理器库使预处理器可以完成您从未想象过的事情(例如 C++98 中的有效可变参数宏),但受到预处理器固有限制的约束 - 所以,抱歉,无法做到。

唯一已知的中间补救措施是为宏保留 ALL_UPPERCASE_IDENTIFIERS,并始终将它们用于宏。它在一定程度上减少了名称冲突问题。不幸的是,C 标准库定义了许多小写宏,或者允许它们的存在,例如 assert,但它们只是其中的几个。

从实际角度来看,主要问题在于 Windows 编程,其中 Microsoft 的 [windows.h] 标头定义了无数个非大写宏,默认情况下包括 minmax 与 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 and max which conflict with the C++ standard library.

So, for Windows C++ programming, always define NOMINMAX before including [windows.h].

Cheers & hth.,

美人骨 2024-10-08 05:01:23

我曾经相信你尝试过的同样的技巧确实有效,因为我自己曾经使用过它。但我最终发现它实际上根本不起作用。简单的答案是否定的,您不能保存定义的当前值,更改它,然后恢复旧值。预处理器根本不是这样工作的。一旦定义了新值,旧值就消失了。

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.

水晶透心 2024-10-08 05:01:23

对我有用的一个技巧是在类中使用枚举。

class foo
{
public:
  enum { blah = 10 } myenum;
}

就可以使用

foo:blah

然后当你需要“10”时

。由于它是类的一部分,因此“blah”的其他用法不会发生冲突,并且您可以保存所有 def'ing 和 undef'ing。

One trick that works for me is to use an enum in the class.

class foo
{
public:
  enum { blah = 10 } myenum;
}

Then you can just use

foo:blah

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文