手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

64bit需要做的改变

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

int length = (int) strlen(str);
在LP64模式中strlen返回的是unsigned long,虽然一般不会出现错误,但是在大于2GB的时候,尽管不大可能,但是会出现潜在的错误。

7.更多的微妙的错误

编译器会发现大多数的潜在的类型转换方面的错误,但是您不能仅仅依赖于编译器。

#define INVALID_POINTER_VALUE 0xFFFFFFFF
在32位上上面的宏定义会被经常地用来测试-1,但是在64位机上,这个数值却不是-1,而是4294967295。在64位机上-1是0xFFFFFFFFFFFFFFFF。要避免这个错误,利用const来声明,并指定signed还是unsigned

const signed int INVALID_POINTER_VALUE = 0xFFFFFFFF;
上面的代码在32位和64位机上都会工作的很好。

更有就是32位机上的代码如下

int **p; p = (int**)malloc(4 * NO_ELEMENTS);
这个代码犯了如下的错误就是认为sizeof(int) == sizeof(int *)

实际上在64位上是不对的。

8.signed和unsigned的错误

long k;
int i = -2;
unsigned int j = 1;

k = i j;

printf("Answer: %ld\n", k);
以上的代码在32位机上会得出-1。但是在64位机上却不是的。结果会是4294967295。原因是i j得到的会是unsigned的值,而这个值却会赋给long的k,要避免这个错误,需要进行修改如下:

k = i (int)j;

9.union的错误


下面是个很常见的结构体:

typedef struct {
unsigned short bom;
unsigned short cnt;
union {
unsigned long bytes;
unsigned short len[2];
} size;
} _ucheader_t;
32位机上会工作的很好,但是在64位机上不然。原因是64位机上long 等于4个short.要把unsigned long 修改成 unsigned int. 才能工作好。必须要注意这个细节。

10.big endian和little endian导致的错误

在32位机上的代码有些移植到64位机上出现错误和否还和机器的big endian或little endian有关。比如下面的代码。

long k;
int *ptr;

int main(void)
{
k = 2 ;
ptr = &k;
printf("k has the value %ld, value pointed to by ptr is %ld\n", k, *ptr);
return 0;
}

这段代码在32bit机上编译不会出现错误,因为long 和pointer都是32bit,但是在64位机上不然,尽管如此,假如在little endian的64位机上编译的话,仍然会得到正确的2,但是在big endian的情况下,则会得到0。

假如有疑问的话,下面周详解释一下。

Memory AddressLittle Endian LP64Big Endian LP64
0x0x7fbfffdca0 ptr0x020x00
0x0x7fbfffdca10x000x00
0x0x7fbfffdca20x000x00
0x0x7fbfffdca30x000x00
0x0x7fbfffdca40x000x00
0x0x7fbfffdca50x000x00
0x0x7fbfffdca60x000x00
0x0x7fbfffdca70x00

0x02

11.64位机上性能的降低

这个问题是由于64位机的数据结构的膨胀,对于内存需要的增加,连同存储空间的增加所致。要减少这方面的损失,您能够精心改变您的数据结构中变量定义的顺序。比如下面的例子



12.如何测试您的64位代码

定义一些宏来完成目标,下面是示例:

#if defined (__LP64__) || defined (__64BIT__) || defined (_LP64) || (__WORDSIZE == 64)
printf("I am LP64\n");
#else
printf("I am ILP32 \n");
#endif

13.64位文档和32位文档之间的彼此读取问题

#include <stdio.h>
#include <inttypes.h>

struct on_disk
{
/* ILP32|LP64 Sharing Issue: This should change to int32_t */
long foo;
};
int main()
{
FILE *file;
struct on_disk data;
#ifdef WRITE
file=fopen("test","w");
data.foo = 65535;
fwrite(&data, sizeof(struct on_disk), 1, file);
#else
file = fopen("test","r");
fread(&data, sizeof(struct on_disk), 1, file);
printf("data: %ld\n", data.foo);
#endif
fclose(file);
}

代码不能很好地在32位和64为对同一个文档的操作过程中工作。要fix这个错误,能够配置宏定义,以在64位机上对foo声明为int32_t。要注意这个细节。

14.fortran和c语言混合的问题

下面两个程式演示了这个错误

void FOO(long *l);
main ()
{
long l = 5000;
FOO(&l);
}

subroutine foo( i )
integer i
write(*,*) 'In Fortran'
write(*,*) i
return
end subroutine foo

要避免这个错误,需要在fortran语言中把i声明为INTEGER*8,这相当于64位的long.

最后,结论:64位机提供了对于更多的计算方面的更好的支持,尽管32位代码一般来说能够移植的很好,但是,得注意这些细节方面的问题,这样才能使您的代码一直工作更顺利。


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