C中自引用宏的任何解决方法?我想附加一个宏

时间:2014-12-29 05:52:32

标签: c c-preprocessor

我有一个文件,它使用了我无法控制的包含的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,但我希望修改宏而不是所有代码。

2 个答案:

答案 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指令。)