最近64bit以更低的代价开放到了广大的用户面前,对于需要更大的内存空间,或更精确的浮点数计算的研发者来说,无疑提供了更多的方便。这篇文章的目的是要读者了解对于32bit的源代码向64bit转移所要做的工作。

事实上来说,32bit的代码能够很方便的移植到64位机上,因为64位提供了对32位很好的支持,只有在您有以下的需要的时候,尝试去修改您的代码

  • 获得超过4GB内存的支持。
  • 获得超过2G大小文档的支持
  • 获得更精确的浮点数运算
  • 获得64位机优化的数学运算库
  • 否则,只需要重新编译您的32位代码,that's ok!

    1。ILP32和LP64 数据模式

    大多数unix系统的数据模式是采用LP64bit的,long和pointer是8个字节64位的,相对于32bit的4个字节。将来windows或许会采用一种数据模式LLP64,只是对于pointer采用64bit,其他的和32位相同。这里以表格的方式显示两者之间的差别

    Data TypeILP32 (bits)LP64 (bits)
    char8No change
    short16No change
    int32No change
    long long64No change
    long3264
    pointer3264

    基本上移植到64bit的错误都是来自误以为int long pointer都是64bit的,实际则不然。下面是个程式演示了这个错误。

    1 int *myfunc(int i)
    2 {
    3 return(&i);
    4 }
    5
    6 int main(void)
    7 {
    8 int myint;
    9 long mylong;
    10 int *myptr;
    11
    12 char *name = (char * ) getlogin();
    13
    14 printf("Enter a number %s: ", name);
    15 (void) scanf("%d", &mylong);
    16 myint = mylong;
    17 myptr = myfunc(mylong);
    18 printf("mylong: %d pointer: %x \n", mylong, myptr);
    19 myint = (int)mylong;
    20 exit(0);
    21
    22 }
    上面的代码是错误的,需要进行修正。

    移植的第一项工作,是让编译器能检测到64位的错误。这根据编译器的不同而变化。对于IBM的XL 编译器家族来说,有用的参数是-qwarn64 -qinfo=pro. 把您的代码编译成64bit需要加上-q64,对于gcc编译器来说则是加上-m64,下面列举一些编译64位一些有用的gcc参数。

    OptionDescription
    -WpaddedWarns that padding was added to the structure.
    -WformatCheck calls to printf and scanf have correct format strings.
    -Wsign-compareWarn when a comparison between signed and unsigned values could produce an incorrect result when the signed value is converted to unsigned.
    -Wsign-compareWarn when a comparison between signed and unsigned values could produce an incorrect result when the signed value is converted to unsigned.
    -WconversionWarn if a prototype causes a type conversion that is different from what would happen to the same argument in the absence of a prototype.
    -Wpointer-arithWarn about anything that depends on the function pointer or of void *.

    下面演示以下编译上面代码所出现的提示信息。

    % xlc -q64 -qformat=all -qwarn64 test.c

    "test.c", line 12.30: 1506-745 (I) 64-bit portability: possible incorrect pointer through conversion of int type into pointer.
    "test.c", line 15.36: 1506-1191 (W) Invalid int format for long argument type in argument 2.
    "test.c", line 16.25: 1506-742 (I) 64-bit portability: possible loss of digits through conversion of long int type into int type.
    "test.c", line 17.32: 1506-742 (I) 64-bit portability: possible loss of digits through conversion of long int type into int type.
    "test.c", line 18.39: 1506-1191 (W) Invalid int format for long argument type in argument 2.
    "test.c", line 19.25: 1506-742 (I) 64-bit portability: possible loss of digits through conversion of long int type into int type.

    2。缺少原型的转换方面的考虑

    上面的代码char *name = (char * ) getlogin();

    会出现错误的,32位的int要转换成64位会出现错误的,要避免这种错误,include正确的头文档<unistd.h>,里面有getlogin()的原型。

    3。定制数据格式的错误

    (void) scanf("%d", &mylong);

    要避免这个错误,修改成这样(void) scanf("%ld", &mylong);

    printf("mylong: %d pointer: %x \n", mylong, myptr);
    修改成printf("mylong: %ld pointer: %p \n", mylong, myptr);

    4.赋值的错误

    myint = mylong;
    错误出现在64位的值赋给32位的

    5.数值参数的传输错误

    myptr = myfunc(mylong);会出现传递时的转换类型错误

    6.类型强制转换出现的错误

    myint = (int)mylong;

    文章整理:西部数码--专业提供域名注册虚拟主机服务
    http://www.west263.com
    以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!