C预处理器:重定义宏,宏重载

tzxcd3kk  于 2023-05-16  发布在  其他
关注(0)|答案(2)|浏览(210)

下面的代码有一个FLAG控制的宏,在编译时使用func 1或func 2。我想让它在编译时通过使用“FLAG”宏(定义/取消定义)在2个函数之间切换,就像在main()上所做的那样。这只是一个示例,将在多个文件中使用。
我的问题是,这只执行func 1(),因为预处理器已经将符号分配给func_wrapper,我没有改变它。另外,如果执行#undef func_wrapper,则需要通过添加更多代码来重新定义它。
我的问题是,是否有可能实现这一点,而不必每次都重新定义func_wrapper。这有点像当FLAG未定义时,让预处理器对宏进行另一次传递,并再次检查定义的定义。
我想得到类似以下代码的东西:

#include "functions.h"
#include "functions2.h"

#define FLAG

#ifdef FLAG
#define func_wrapper func1
#endif

#ifndef FLAG
#define func_wrapper func2
#endif

int main(){

    func_wrapper();

    #undef FLAG

    func_wrapper();

}

运行如下:

...
//same as previous one
...
int main(){

    func_wrapper();

    #undef FLAG
    #ifndef FLAG
    #undef func_wrapper
    #define func_wrapper func2
    #endif

    func_wrapper();

}
gk7wooem

gk7wooem1#

如果有可能在不每次都重新定义func_wrapper情况下实现
不知道
使预处理器对宏进行另一次传递
你得再打一遍。

#include "functions.h"
#include "functions2.h"

#define FLAG

#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif

int main() {
    func_wrapper();
    #undef FLAG
#undef func_wrapper
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif
    func_wrapper();
}

你可以把它放在一个标题中。

// resolve_flag.h
#ifdef func_wrapper
#undef func_wrapper
#endif
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif

// main.h
#include "functions.h"
#include "functions2.h"

#define FLAG
#include "resolve_flag.h"

int main() {
    func_wrapper();
    #undef FLAG
    #include "resolve_flag.h"    
    func_wrapper();    
}

但也许只使用运行时和一些全局状态:

bool flag = 0;
void func_wrapper(void) {
     flag ? func1() : func2();
}

int main() {
     func_wrapper();
     flag = 1;
     func_wrapper();
}
332nm8kg

332nm8kg2#

如果func_wrapper * 不是 * 一个宏,你可以用一行源代码将它重新定义为其他的东西:

#include "functions.h"
#include "functions2.h"

// default definition.  We can use macros to have some callers call func2 directly
static inline void func_wrapper() {
  func1();
}
// #define func_wrapper func2

int main()
{
    func_wrapper();    //  call func1
    #define func_wrapper func2
    func_wrapper();    //  call func2

    #undef func_wrapper  // now it's back to an alias for func1
}

这是相当丑陋,似乎相当黑客,并失去了单独的名称FLAG,这大概有一些有用的语义意义。我不建议你这么做。
如果该函数实际上接受参数,则 Package 器必须传递它们。
如果你可以使用嵌套函数,一个GNU C扩展,你实际上根本不需要CPP。这在GCC中有效,但在clang(Godbolt)中无效。

// default definition
static inline void func_wrapper() {
  func1();
}

int main()
{
    func_wrapper();

    static inline void func_wrapper(){ func2(); }  // shadows the global definition

    func_wrapper();
}

这甚至更糟,因为 Package 器定义会使您在内部使用它的函数变得混乱。

相关问题