在温伯格的《你的灯亮着么?》(《are your lights on?》)一书中,对我们编程过程中经常会遇到的一些问题进行了深入浅出的分析。其中一条基本原则就是找出“问题的真正所在”。下面结合在代码移植过程中遇到的一个问题来谈谈找出“问题的真正所在”的重要性。
在tru64 unix系统下的代码中,存在这样的一段代码:
#define F(a) f_##a##()
这段代码意思为使用F(x)宏定义时,调用函数f_a()。在tru64 unix 5.1B,cxx编译器下编译通过,运行也没有任何问题。
当移植到solaris 5.9,使用gcc编译时,这段代码的编译出现了问题,经过查找,我们找到了“问题所在”,改为下述方式
#define F(a) f_##a()
就不会再有问题了,原因是gcc不支持tru64下的编译器的语法表达方式。
但我们要把两种操作系统的代码合并在一起,显然直接把原来的删除替换成现在的是不行的,这样我们自然而言的想到使用宏定义区分:
#if defined(TRU64)
#define F(a) f_##a##()
#elif defined(sun)
#define F(a) f_##a()
#endif
由于我们的移植是从tru64 unix到solaris 系统,所以上述的宏定义似乎是没有任何问题,而且也能够达到我们想要的结果。但让我们再多想一步,造成上述差异的问题真的是操作系统造成的么?当然不是,是编译器。所以使用操作系统宏来区分虽然也解决了问题,却不是对问题的最好的解决方法:
#if defined(_cxx)
#define F(a) f_##a##()
#elif defined(GNUC)
#define F(a) f_##a()
#endif
这样定义宏更能说明进行区分的原因。
我们更进一步考虑,为什么两个编译器要使用不同的表达方式呢?因为对c/c++标准的支持程度不同,或者说,对c/c++标准没有定义的部分的实现方式不同。应该说,g++对标准的支持更好一些,那以后别的系统的编译器会怎么样呢?我们不知道,但不妨假设应该是对c/c++标准的支持越来越好,所以,最终,我们可以把上述语句写成:
#if defined(_cxx)
#define F(a) f_##a##()
#else
#define F(a) f_##a()
#endif
阅读(1001) | 评论(0) | 转发(0) |