使用宏进行动态版本选择
Posted
技术标签:
【中文标题】使用宏进行动态版本选择【英文标题】:Dynamic version selection with macros 【发布时间】:2018-09-26 03:14:20 【问题描述】:我在我的代码中使用了第 3 方库,我正在尝试测试它的最新版本。我的其他同事使用的是旧版本,我应该提交适用于两个版本的代码。 现在的问题是,我正在使用的函数在 2 个版本中具有不同数量的参数。
//eg- in ver_old
DoSomething(para 1, para 2);
//ver_new
DoSomething(para 1, para 2, para 3 , para 4);
如果我按照ver_new修改代码,有旧代码的就不能编译,如果我用ver_old,我就不能编译代码。库中有一个函数可以将版本作为 *char 返回。
有没有办法可以使用#if #else #endif
来选择要编译的方法?或者使用带有#define
的版本字符?
谢谢。
编辑 - 我将无法编辑库中的代码。
【问题讨论】:
您可以为新添加的参数设置默认值,以便新旧参数都能正常工作。恕我直言,使用宏使代码在两个版本中都能正常工作是作弊(顺便说一句,“动态”和“宏”通常不能很好地结合在一起) 我想这个库提供了一个宏来告诉版本号,所以你可以在上面使用#if
。否则你必须在你身边创建等价物。
【参考方案1】:
您可以在较新的库中实现两个版本,因此您只有一个只有两个参数。它可以调用较新的版本,为缺少的参数提供一些默认值。
【讨论】:
【参考方案2】:您的问题可能不够清楚,但这是获得答案的重要提示:
库中有一个函数可以将版本作为 *char 返回。
甚至在您的代码被编译之前,宏就会被扩展。您无法根据函数的返回值进行条件编译(您只能在运行时调用它)。
如果您的代码应该适用于旧版本和新版本,您需要寻找不同的解决方案。对于其他参数,您可以提供默认值:
foo(int x, double y); // old
foo(int x, double y, float z = 0); // new
【讨论】:
【参考方案3】:您可以强制调用者使用#define
一个宏,例如#define NEW_LIB
,然后在新代码中使用#ifdef
。如果已定义,则使用新版本,否则使用旧版本。
否则,仅供参考,C兼容的替代函数重载:
typedef struct
int a;
char b;
double c;
char* d;
new_param_list;
void DoSomethingNew (new_param_list* list);
#define DoSomething(...) DoSomethingNew(&(new_param_list) __VA_ARGS__ )
如果传递了 2 个参数,则其他 2 个将设置为零。
对于不支持复合字面量的 C++ 编译器,宏同样可以调用构造函数 new_param_list(int a, char b, double c, char* d)
来获取匿名临时对象。
【讨论】:
以上是关于使用宏进行动态版本选择的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Xcode Profiling and Archiving Builds 中设置 DEBUG 和 NDEBUG 宏?