假设我有一些代码使用名称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,但如果该解决方案也适用于大多数其他编译器,那将是可爱的。
答案 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 ,默认情况下包括min
和max
与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。