编写移植性好的C代码
众所周知,通过使用条件编译,可以让我们的C代码支持不同的平台。但是在代码中大量运用#ifdef, #endif这样的预处理指令显然是不妥的,因为这些代码分散在所有的代码中,非常难维护。将来如果要再添加一个平台的支持,要在所有代码中search 这些预处理指令。所以,很容易想到的一种改良方法是专门做一个.h文件来做这个事情,比如platform_specific.h:
#ifdef WIN32
inline function1() { ...... }
inline function2() { ...... }
#endif
#ifdef LINUX
inline function1() { ...... }
inline function2() { ...... }
然后将和平台无关的代码写在一个类似platform_independent.c中
这样做也不是非常好,因为在platform_specific.h中还是有大量的#ifdef, #endif
最好的解决方案是这样:在platform_specific.h中这样写:
#ifdef WIN32
#include "win32_platform.h"
#endif
#ifdef LINUX
#include "linux_platform.h"
#endif
这样,和平台相关的逻辑就被放到了一个个单独的文件中。这样的好处是,首先platform_specific.h中#ifdef, #endif的代码大量减少;在一个team工作的时候,很容易分工,开发平台相关代码的人员各自有各自的源代码,不会和其他人冲突;CVS中只需要维护 一颗代码树,无需建立分支,免去分支建立、合并的麻烦;通过这种方式,还可以再进一步抽象,如Solaris和AIX两个平台,可以再抽象建立一个 unix_platform.h,里面放Solaris和AIX共有的一些东西,我们首先include这个unix_platform.h,然后将 Solaris和AIX不同的地方再分别建文件,诸如solaris_platform.h和aix_platform.h;最后一个好处是,如果将来要 新增一个platform的支持,非常简单,再新增一个xxx_platform.h即可!
OK,这样做有一个注意点,就是,在 win32_platform.h, linux_platform.h这些代码中,可以将所有的function都做成inline的,这些function要简短,扼要,而且千万不要包含 任何平台无关的代码(因为平台无关的代码应该被抽象出去,不是放在这里),比如,我们针对一个系统调用,在不同的平台可能函数名不一样,那么,在这里的 function中可能就是一句代码,那就是不同的平台分别调不同的函数名。
#ifdef WIN32
inline function1() { ...... }
inline function2() { ...... }
#endif
#ifdef LINUX
inline function1() { ...... }
inline function2() { ...... }
然后将和平台无关的代码写在一个类似platform_independent.c中
这样做也不是非常好,因为在platform_specific.h中还是有大量的#ifdef, #endif
最好的解决方案是这样:在platform_specific.h中这样写:
#ifdef WIN32
#include "win32_platform.h"
#endif
#ifdef LINUX
#include "linux_platform.h"
#endif
这样,和平台相关的逻辑就被放到了一个个单独的文件中。这样的好处是,首先platform_specific.h中#ifdef, #endif的代码大量减少;在一个team工作的时候,很容易分工,开发平台相关代码的人员各自有各自的源代码,不会和其他人冲突;CVS中只需要维护 一颗代码树,无需建立分支,免去分支建立、合并的麻烦;通过这种方式,还可以再进一步抽象,如Solaris和AIX两个平台,可以再抽象建立一个 unix_platform.h,里面放Solaris和AIX共有的一些东西,我们首先include这个unix_platform.h,然后将 Solaris和AIX不同的地方再分别建文件,诸如solaris_platform.h和aix_platform.h;最后一个好处是,如果将来要 新增一个platform的支持,非常简单,再新增一个xxx_platform.h即可!
OK,这样做有一个注意点,就是,在 win32_platform.h, linux_platform.h这些代码中,可以将所有的function都做成inline的,这些function要简短,扼要,而且千万不要包含 任何平台无关的代码(因为平台无关的代码应该被抽象出去,不是放在这里),比如,我们针对一个系统调用,在不同的平台可能函数名不一样,那么,在这里的 function中可能就是一句代码,那就是不同的平台分别调不同的函数名。