4

假设我在 C 中有一个名为FOO. 还有两个宏叫做BAR1and BAR2,它们基本上是同一个宏的两种风格。我想编写一个宏BAR,使其扩展到BAR1在使用之前调用FOO某处的函数中BARBAR2否则。例如:

void func1(void)
{
    FOO();
    ...
    BAR();
}

相当于

void func1(void)
{
    FOO();
    ...
    BAR1();
}

而这个功能:

void func2(void)
{
    BAR();
}

相当于

void func2(void)
{
    BAR2();
}

我想避免在运行时引入全局变量或进行额外的检查。这甚至可能吗?

4

2 回答 2

3

简短的回答:不。C 预编译器对函数限制一无所知,因此即使您设法根据需要修改BAR宏,也不会限于当前函数。

现在,如果您愿意,可以向BAR宏添加一些检查。并且可以编写这些检查以在编译时解决,因此不会产生运行时开销。

例如:

extern char _sentinel_[2];

#define FOO() char _sentinel_;

#define BAR() if (sizeof(_sentinel_) == 1) BAR1() else BAR2()

诀窍是变量的查找_sentinel_将解析全局变量或局部变量,具体取决于FOO(). 并且由于 中的条件if是编译器常量,编译器将优化另一个分支。

于 2013-08-06T10:31:18.110 回答
2

我尝试使用gotos 的破解失败了,因为当FOO()不使用时,跳转标签缺少BAR(). 但是,不要害怕,我想出了一个更严重的黑客攻击。

您可以使用#includes 而不是宏来表示FOO()and BAR()。这将允许您完全控制代码的扩展方式。

/* FOO file */
#define BAR_IS_BAR2
/* whatever code FOO needs to do */

/* BAR file */
#ifdef BAR_IS_BAR2
    BAR2();
    #undef BAR_IS_BAR2
#else
    BAR1();        
#endif

/*...in you source code...*/
void func1 () {
    #include "FOO"
    /*...*/
    #include "BAR"
}

void func2 () {
    #include "BAR"
}
于 2013-08-06T11:01:45.213 回答