假设我在C中有一个名为FOO
的函数宏。还有两个名为BAR1
和BAR2
的宏,它们基本上是同一个宏的两种口味。我想编写一个宏BAR
,以便在使用BAR1
前调用FOO
的函数扩展为BAR
,否则调用BAR2
。例如:
void func1(void)
{
FOO();
...
BAR();
}
等同于
void func1(void)
{
FOO();
...
BAR1();
}
虽然这个功能:
void func2(void)
{
BAR();
}
等同于
void func2(void)
{
BAR2();
}
我想避免在运行时引入全局变量或进行额外的检查。这甚至可能吗?
答案 0 :(得分:3)
简短回答:不。 C预编译器对函数限制一无所知,因此即使您设法根据需要修改BAR
宏,也不会局限于当前函数。
现在,如果您愿意,可以向BAR
宏添加一些检查。并且可以编写这些检查以在编译时解决,因此不会产生运行时开销。
例如:
extern char _sentinel_[2];
#define FOO() char _sentinel_;
#define BAR() if (sizeof(_sentinel_) == 1) BAR1() else BAR2()
诀窍是变量_sentinel_
的查找将解析全局变量或本地变量,具体取决于FOO()
的使用。由于if
中的条件是编译器常量,编译器将优化其他分支。
答案 1 :(得分:2)
我尝试使用goto
的操作失败,因为在未使用FOO()
时,BAR()
缺少跳转标签。但是,不要害怕,我已经提出了更严重的黑客攻击。
您可以使用#include
代替FOO()
和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"
}