使用 #ifdefs 进行代码选择会创建丑陋的结构 - 替代方案

Using #ifdefs for code selection creates ugly constructs - alternatives?

本文关键字:结构 方案 创建 #ifdefs 代码 选择 使用      更新时间:2023-10-16

目前我的代码看起来大致像

#ifdef A
#include "include_a.h"
#endif
#ifdef B
#include "include_b.h"
#endif
void func_A()
{
#ifdef A
    do_stuff_a();
#endif
}
void func_B()
{
#ifdef B
    do_stuff_b();
#else
    do_other_stuff();
#endif
}
void func_C()
{
    do_stuff_c();
}
int main(void)
{
#ifdef A
#ifdef B
    do_AB_stuff();
#else
    do_A_stuff();
#endif
func_A();
func_B();
func_C();
return 0;
}
原因是

:我正在使用 cmake 来链接其他库/标头。如果这些标头/库是链接的,则调用包含的函数是有意义的,否则,编译将失败。这允许我在有和没有其他库的情况下运行程序(例如,如果我只想测试func_C(),而没有func_B()func_A()的计算过载,或者如果库A和B在系统上不可用)。
尽管如此,这还是相当丑陋的代码,周围有很多#ifdefs。因此,有没有办法获得相同的功能(最好由 cmake-script 控制),但不必使用所有这些#ifdefs

根据库 A 和 B 的大小,您可以编写存根库,其中包含不执行任何操作或返回硬编码值或任何有意义的函数。然后,您可以链接到真实库或存根库以进行测试func_C()

例如,如果真实库的 API 只是

include_a.h:
void do_stuff_a();
void do_A_stuff();

您的存根可能是:

stub_a.cpp:
void do_stuff_a() {}
void do_A_stuff() {}

然后,您可以摆脱所有#ifdef A,如果不使用该库,则只需与存根文件链接。

您可以创建所谓的存根库/实现,然后决定是链接到该库还是具有真正实现的库。

文件a_stub.c

#include "include_a.h"
void func_A() {} // Does nothing. Returns a placeholder value if necessary.

文件a_real.c

#include "include_a.h"
void func_A() { do_stuff_a(); }

B 和 C 相同。然后,您可以根据自己的兴趣选择*_real.c*_stub.c(即定义A宏、B宏和C宏的情况)。

编辑:这可能是@Baruch在另一个答案中评论的内容。发布答案后,我看到了他的评论。