我们最近完成的一个项目是移植一个大型的32位应用程序,它可在64位环境中支持11个操作系统平台..
编码惯例与移植考虑
除了遵循操作系统编译器文档所推荐的标准64位编码惯例之外,以下还有一些意见及小提示,也许在计划向64位移植时,可帮得上忙:
·如果可能且现实,把源代码转换为ANSI C/C++。这将简化64位移植过程,甚至将来的移植也会受益。
·你的目标操作系统同时支持32位与64位应用程序吗?应及早知道答案,因为它会对是否移植产生影响。例如:在Solaris上,使用系统命令isainfo检查32位与64位程序的兼容性。
% isainfo -v 64-bit sparcv9 applications 32-bit sparc applications |
·如果你的源代码已经被如CVS之类的版本控制系统管理,在移植之前,将会有助于实现第一个程序。由于为了移植,我们常常需要对全局代码作大量的改动,而有时需要回返到前一个版本的代码,版本控制系统正好是这方面的能手。
·你的应用程序使用或加载32位的第三方库吗?如果有,在计划期间就最好决定,是否这些库也应该升级为64位。如果long与指针不能在你的主程序与第三方库之间传递,那么只要操作系统可以同时运行32位与64位程序,就没有必要移植为64位了;如果操作系统不支持,那么就要计划把第三方程序也移植为64位了。
·如果你的程序在运行时动态地加载库,并仍然使用对load()的老式调用,那么应使用dlopen()来纠正在主程序与第三方模块之间的数据传递问题,尤其是在dlopen()出现之前的那些老式AIX程序更应如此。为在AIX上打开运行时链接,链接器中必须加上 -brtl选项,并带上 -L ":"以指定库的位置。为提高兼容性,你的主程序和所有通过dlopen()加载的库,都必须使用运行时链接重新编译。
·考虑向后兼容性。当移植到64位平台时,向后兼容性问题变得尤为重要,必须对现有测试方案进行改进,以包含老式32位测试和新式64位测试。
工具 对大型的源代码编制一个详细目录清单,特别是共享于跨32位与64位平台的,而且要对每一处修改进行评估,不管它是多么微不足道,都是一项令人畏惧的任务,因为忽略转换问题的潜在性及引入新错误的概率都非常高。可是,使用一些64位工具及技巧,许多的这种潜在性问题能在预编译阶段、编译阶段、和运行时捕捉到。下面是一些可用的工具:
·预编译阶段。在编译器中使用 -errchk=longptr64选项,可启用lint,对于捕捉类型转换的不匹配、隐式函数声明、及参数不匹配等非常有效,例3演示了典型的lint警告,当然也有其他lint类型的程序,如FlexLint(http://www.gimpel.com/html/products.htm)。
·编译时技巧。调整编译器警告级别,以保证至少在项目的初始阶段,没有抑制任何警告信息。对多平台环境而言,在不同的操作系统上,编译同一源代码,将会产生不同的问题,要充分利用这一点,对比分析出问题所在。
·编译时和运行时工具。先进的工具,如 Insure++ 或 Purify for 64-bit,都针对至少一个平台,在任何针对运行时和编译时的开发环境中,都派得上用场。
·运行时工具。试一下dbx,其由每一个Unix编译器提供;或者ddd(数据显示调试器),它是Unix上的dbx和gdb的图形接口(http://www.gnu.org/software/ddd/)。
例3:典型lint警告
warning: implicit function declaration: main warning: argument does not match remembered type: arg #1 warning: passing 64-bit integer arg, expecting 32-bit integer: MyProc(arg 7) warning: assignment of 64-bit integer to 32-bit integer warning: function argument ( number ) used inconsistently warning: comparing 32-bit integer with 64-bit integer |
结论 花一些时间来做前期的计划和调查,虽说不一定能达到事半功倍的效果,但从获得的结果来看还是值得的。而当程序中没有任何一处工作正常时,也不要气馁,此时,应仔细并系统地检查代码并找出问题所在。随着内存及数据数量的逐年高速增长,我们有理由相信,跟64位程序所带来的好处相比,那些移植转换时的艰难过程根本算不了什么。
查看本文来源