使用#ifdefs 进行代码选择会创建丑陋的结构 - 替代方案?
Using #ifdefs for code selection creates ugly constructs - alternatives?
目前我的代码看起来大致像
#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 链接额外的 libraries/headers。如果那些 headers/libraries 是链接的,那么调用包含的函数是有意义的,如果不是,编译将失败。这使我可以 运行 使用和不使用附加库的程序(例如,如果我只想测试 func_C()
,而没有 func_B()
和 func_A()
的计算过载,或者如果库 A 和 B 在系统上不可用)。
尽管如此,这仍然是相当丑陋的代码,周围有很多 #ifdefs
。因此,有没有办法获得相同的功能(最好由 cmake 脚本控制),但不必使用所有这些 #ifdefs
?
根据库 A 和 B 的大小,您可以编写存根库,其中包含不执行任何操作的函数或 return 硬编码值或任何有意义的内容。然后你可以 link 使用真实库或存根库进行测试 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
,只使用存根文件 link。
您可以创建所谓的存根 library/implementation,然后决定是 link 到该库还是具有实际实现的库。
文件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 在另一个答案中评论的内容。我在发布答案后看到了他的评论。
目前我的代码看起来大致像
#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 链接额外的 libraries/headers。如果那些 headers/libraries 是链接的,那么调用包含的函数是有意义的,如果不是,编译将失败。这使我可以 运行 使用和不使用附加库的程序(例如,如果我只想测试 func_C()
,而没有 func_B()
和 func_A()
的计算过载,或者如果库 A 和 B 在系统上不可用)。
尽管如此,这仍然是相当丑陋的代码,周围有很多 #ifdefs
。因此,有没有办法获得相同的功能(最好由 cmake 脚本控制),但不必使用所有这些 #ifdefs
?
根据库 A 和 B 的大小,您可以编写存根库,其中包含不执行任何操作的函数或 return 硬编码值或任何有意义的内容。然后你可以 link 使用真实库或存根库进行测试 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
,只使用存根文件 link。
您可以创建所谓的存根 library/implementation,然后决定是 link 到该库还是具有实际实现的库。
文件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 在另一个答案中评论的内容。我在发布答案后看到了他的评论。