复合条件编译开关的使用


正在做的项目随着开发的进行出现了众多的分支版本。
目前我们还是使用传统的编译开关的方法进行版本代码的区分。
最近遇到的问题是,有一段代码在两个分支版本中需要被激活,而在其他所有版本中不需要被编译。
而两个版本分别由两个编译项来表示,也就是说这两个版本可能共享部分代码。
所以留给我的选择是,要么把公用的代码再复制一份,分别以#if…#endif 包围然后进行编译;要么就是用更简单地方法只保留一份代码,同时共享给两个版本使用。
当时就在想,#if是否可以添加一些运算符进行一些多条件的比较呢。
回到家里,用Dev C++测试了一下,果然成功。
代码如下:

#include <stdio.h>
#include <stdlib.h>

#define SW1_OPTION1     0
#define SW1_OPTION2     1
#define SW1_OPTION3     2

#define SW2_OFF         0
#define SW2_ON          1

#define COMPILE_SW1     SW1_OPTION2
#define COMPILE_SW2     SW2_ON

int main(int argc, char *argv[])
{
#if ((COMPILE_SW1 == SW1_OPTION2) && (COMPILE_SW2))
	printf("True result\n");
#else
	printf("False result\n");
#endif
	system("PAUSE");
	return 0;
}

第16行的代码进行的就是复合条件的编译开关,当2个条件都为True时,将执行第17行的代码,否则将执行第19行的代码。
经过测试,运行结果没有问题。

当然,各种比较运算符包括>,<,!=等等;各种逻辑运算符包括 || 和 ! 都可以在这里被使用。
类似代码如下:

#if ((COMPILE_SW1 > SW1_OPTION1) && !(COMPILE_SW2))
#if ((COMPILE_SW1 != SW1_OPTION1) || (COMPILE_SW2))

追记:
最近在写另一篇文章时发现,从gcc 4.x版本开始,对宏定义的检查变得苛刻了。坦白地说,原本在C99标准里,就没提到可以在#if语句中使用前文所述的比较方法。gcc 4.x只是在更忠实地实现原本的标准吧。(之前使用的Dev C++的gcc版本是3.4.2)

使用gcc 4.x对上面的程序进行编译,会出现这样的错误。
[stextbox id=”alert” color=”000000″ bgcolor=”e5a194″
big=”true”]missing binary operation before token “(“[/stextbox]
在花了我大约半个小时寻找出错的原因后,我决定用下面的代码来实现同样的功能。

if (COMPILE_SW1 == SW1_OPTION2) && (COMPILE_SW2) {
	printf("True result\n");
} else {
	printf("False result\n");
}

因为if语句中所有的比较元素都是宏定义,在编译器对if进行编译之前,等待被比较的值都已经被设定好了。编译器的优化选项自然会将必然是FALSE条件的语句排除在编译范围外,所以不用担心程序在编译之后被迫增加了不必要的代码。

Tagged on:

发表评论

电子邮件地址不会被公开。