为32位/ 64位移植的典型缺陷是:
由程序员那的sizeof(无效*)== 4 *的sizeof(char)的隐含的假设。 如果你正在做这个假设,例如以这种方式分配数组(“我需要20个指针,因此我分配80个字节”),您的代码在64位上断开,因为它会导致缓冲区溢出。
“小猫杀手”,int x =(int)&something; (并且相反,void * ptr =(void *)some_int)。再次假设sizeof(int)== sizeof(void *)。这不会导致溢出,但会丢失数据 - 指针的高32位,即。
这两个问题是一类称为混叠型(两种类型之间的二进制表示水平假设身份/互换性/等效)的,并且这样的假设是常见的;像在UN * X上一样,假设time_t,size_t,off_t是int,或者在Windows上,HANDLE,void *和long可互换等等。
关于数据结构/堆栈空间使用的假设好)。在C/C++代码中,局部变量分配在堆栈上,由于下面的点,因此在32位和64位模式之间使用的空间不同,并且由于传递参数的不同规则(通常在堆栈上有32位x86,64位x86部分在寄存器中)。刚刚摆脱32位默认堆栈大小的代码可能会导致64位堆栈溢出崩溃。 这是相当容易发现作为崩溃的原因,但取决于可能难以解决的应用程序的可配置性。 32位和64位代码之间(由于不同的代码尺寸/高速缓存足迹,或不同的存储器访问特征/图案,或不同的调用约定)
时间差异可能会破坏“校准”。说,for(int i = 0; i < 1000000; ++ i)sleep(0);很可能将会有不同的时间对32位和64位...
最后,ABI(应用程序二进制接口)。通常,64位环境中存在两个主要的“分支”,IL32P64(Win64使用的是--int和long是int32_t,只有uintptr_t/void *是uint64_t,根据来自)和LP64(UN * X使用的是什么 - int是int32_t,long是int64_t和uintptr_t/void *是uint64_t),但也存在不同对齐规则的“细分” - 一些环境假设长,浮动或双对齐,而其他人则假定它们以四个字节的倍数对齐。在32位Linux中,它们全部以四个字节对齐,而在64位Linux中,它们以八字节倍数浮动对齐四位,长两位。 这些规则的结果是,即使数据类型声明完全相同,在很多情况下,bith sizeof(struct {...})和结构/类成员的偏移量在32位和64位环境之间也是不同的。 除了影响阵列/向量分配之外,这些问题还会影响数据输入/输出。通过文件 - 如果32位应用程序编写例如struct {char a; int b; char c,long d;双e}到同一个应用程序重新编译为64位的文件读入,结果将不会完全符合所希望的。 刚刚给出的例子只是关于语言原语(char,int,long等),但当然会影响各种平台相关/运行时库数据类型,无论size_t,off_t,time_t,HANDLE,本质上是任何非平凡的结构/联合/ class ... - 所以这里的错误空间很大,
然后还有更低层次的差异,用于手动优化组装(SSE/SSE2/...); 32位和64位具有不同的(数量)寄存器,不同的参数传递规则;所有这些都强烈地影响着这种优化如何执行,并且很可能如在32位模式下提供最佳性能的SSE2代码将需要重写/需要增强以提供最佳性能的64位模式。对于32位和64位,还有代码设计约束条件非常不同,尤其是在内存分配/管理方面;一个经过仔细编码的应用程序“最大限度地利用mem可以获得32位”将具有复杂的逻辑,如何/何时分配/释放内存,内存映射文件使用率,内部缓存等 - 其中大部分将在64位上是不利的,你可以“简单地”利用巨大的可用地址空间。这样的应用程序可能会重新编译为64位就好了,但在那里执行比一些“古老的简单的不推荐的版本”,它没有所有的最大化 - 32位窥视孔优化。因此,最终它也是关于增强/增益的,这就是更多的工作,部分是编程,部分是设计/需求。即使你的应用在32位和64位环境中都干净地重新编译,并在两者上都得到验证,它实际上是从64位受益?是否可以/应该对代码逻辑进行更改,以使其在64位中执行更多/更快的运行?你能做这些改变而不破坏32位向后兼容性吗?对32位目标没有负面影响?增强功能在哪里,你能获得多少? 对于大型商业项目,这些问题的答案往往是路线图上的重要标记,因为您的出发点是一些现有的“货币制造商”...
awsome anwser :)只是我在找:) – 2013-02-21 13:12:33
@FredrikBostonWestman那么你应该接受它! – gsamaras 2015-04-04 15:41:49