保留预处理器定义

时间:2010-11-08 21:14:36

标签: c++ save c-preprocessor

  

可能重复:
  Can I redefine a C++ macro then define it back?

假设我有一些代码使用名称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,但如果该解决方案也适用于大多数其他编译器,那将是可爱的。

4 个答案:

答案 0 :(得分:24)

是的,假设你的编译器支持push / pop宏指令(visual c ++,gcc,llvm都这样做):

#define BLAH 10

#pragma push_macro("BLAH")
#undef BLAH

#define BLAH 5

...

#pragma pop_macro("BLAH")

答案 1 :(得分:4)

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

Boost预处理器库让预处理器做了你从未想象过的事情(比如C ++ 98中有效的可变参数宏),但受到预处理器固有限制的约束 - 所以,没有办法,遗憾。

唯一已知的中途补救方法是为宏保留ALL_UPPERCASE_IDENTIFIERS,并始终将它们用于宏。它有点减少名称冲突问题。不幸的是,C标准库定义了许多小写宏,或允许它们存在,例如, assert,但他们只是少数。

从实际的角度来看,主要的问题是在Windows编程中,Microsoft的[windows.h]标头定义了非大写宏的 zillions ,默认情况下包括minmax与C ++标准库冲突。

因此,对于Windows C ++编程,在包含[windows.h]之前始终定义NOMINMAX

干杯&第h。,

答案 2 :(得分:0)

我曾经相信你试过的那个技巧确实有效,因为我以前经常使用它。但我最终了解到它实际上根本不起作用。简单的答案是NO,您无法保存define的当前值,更改它,然后恢复旧值。预处理器根本不起作用。定义新值后,旧值就消失了。

答案 3 :(得分:-3)

对我有用的一个技巧是在课堂上使用枚举。

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

然后你可以使用

foo:blah

当你需要'10'时。

因为它是课堂的一部分,所以“blah”的其他用法不会发生冲突,你可以保存所有的def'ing和undef'ing。