我有一个文件,它使用了我无法控制的包含的FLAGS
宏。 FLAGS
中的内容并不一致。有时我需要更改FLAGS
以向其添加标记。现在我知道我不能做#define FLAGS FLAGS|MY_FLAG
,但我想如果我将FLAGS
存储在一个临时变量中,然后我可以取消定义它并使用临时和我的标志重新定义它。例如:
// Assume this next line is what's in the include file
#define FLAGS (1|2|4)
// The rest of this is source, assume compile with -DMOD
#ifdef MOD
#define TEMP (FLAGS|8)
#undef FLAGS
#define FLAGS TEMP
#endif
int main()
{
printf("0x%x\n", FLAGS);
}
如果定义了MOD
,则错误为error: 'FLAGS' was not declared in this scope
。我知道我可以将使用FLAGS
的所有实际C代码改为使用FLAGS|MY_FLAG
,但我希望修改宏而不是所有代码。
答案 0 :(得分:3)
完全按照您要做的做的唯一真正的方法是定义一个额外的宏
// Assume this next line is what's in the include file
#define FLAGS_FOR_A (1|2|4)
#define FLAGS FLAGS_FOR_A
// The rest of this is source, assume compile with -DMOD
#ifdef MOD
#undef FLAGS
#define FLAGS ( FLAGS_FOR_A | 8 )
#endif
int main()
{
printf("0x%x\n", FLAGS);
}
宏只是简单的文本替换,在运行时之前计算
答案 1 :(得分:1)
如果使用Boost's "evaluated slots"将宏定义为可修改,则可以在逻辑上等效于#define FLAGS FLAGS|MY_FLAG
:
#include <boost/preprocessor/slot/slot.hpp>
// define FLAGS as a modifiable macro and create a setter for it
#define FLAGS BOOST_PP_SLOT(1)
#define UPDATE_FLAGS BOOST_PP_ASSIGN_SLOT(1)
int main(void) {
// set the initial value of FLAGS
#define BOOST_PP_VALUE (1|2|4)
#include UPDATE_FLAGS
printf("0x%x\n", FLAGS); // 0x7
// update FLAGS with a new value using the old one
#define BOOST_PP_VALUE (FLAGS|8)
#include UPDATE_FLAGS
printf("0x%x\n", FLAGS); // 0xf
}
尽管是巫术,但这完全符合标准C,没有扩展名。仅适用于整数。
(它的工作原理是利用重要的东西:宏不只是扩展到程序代码中,而且还需要扩展以确定是否也遵循#if
分支。从#if
开始指令也能够评估整数数学,这能够扩展实际的数值,并使用它来构造PP_SLOT
的新扩展,不涉及任何宏名称的引用。这都隐藏在后面#include UPDATE_FLAGS
指令。)