C++ 64位的平台兼容性
2014-12-26 15:05
603 查看
最近在工作中遇到了这样的一个问题,在32位的机器上运行的代码移植到64位的机器上时,结果产生了不正确的结果,经过检查发现,是由于指针的截断导致了问题的出现。将DWORD改成DWORD_PTR之后就一切OK。
主要是两个问题:指针截断和数据对齐。C/C++移植的问题1 新的数据类型和函数
1)固定精度:(跟X86或X64无关)
2)平台相关
3) 平台相关指针
2 指针的截断
[MSDN]An int and a long are
32-bit values on 64-bit Windows operating systems. For programs that you
plan to compile for 64-bit platforms, you should be careful not to
assign pointers to 32-bit variables. Pointers are 64-bit on 64-bit
platforms, and you will truncate the pointer value if you assign it to a
32-bit variable.在以前的32位系统中,指针的为32位,在新的64位系统中指针为64位,这样的话,我们以前编
程中常用的指针与int或long等的直接转化,放在新的64位的系统中就会出错,指针高位的值就会丢失,从而产生错误。例如下面的2行代码,在32位上
正确,但是在64位上就会发生指针截断,出现错误:
下面是我们使用新的动态数据类型,从而实现不用修改代码,直接在32位和64位上直接编译:
3 虚拟地址空间 (解决方法:在64位的指针中只不使用高32位,也就等于原来32位中的32位指针了)
在
32位的系统中,一共可以是用的内存为4G,但是对于用户的应用一般只可以使用2G,其他的2G为系统使用,当然你也可以打开3G的开关,这样的话最多就
能使用3G.对于高精度的浮点运算,高强度的数据库处理等,就需要更大的内存,这时候64位给我们带来了福音,在64位上我们最多可以使用16T的内存,
这样就大大提高了性能。但是对于一些没有使用到超过2G的内存,但当中却大量的使用了指针与整型等的强制转化的应用程序,我们可以使用一种简单的方法,使
用编译器的开关VBS:/Largeadressaware:no,使32位的程序移植到64位上。但是这种简单的移植方法,会带来一些弊端:如果被真的
64位所调用,就有可能真的产生指针的截断,同时也没有解决对齐问题和大内存的使用问题。
4 数据类型对齐和补齐
由于对 于不同的cpu架够有不同的数据对齐策列,而且数据的对齐也影响程序的性能和正确性。常用的2个宏:TYPE_ALIGNMENT(type)和
FIELD_OFFSET(type,member)分别用来计算指定类型的对齐值和某复合变量中成员的偏移量。对于复合数据类型,采用递归的计算方法。
对于复合数据类型如果没有对齐,则补齐,保证结尾处地址是该复合数据类型的整数倍。(在C++中可以使用#Program()来设置对齐方式)
5 CPU架构与对齐意外
对
于我们以前的32位,CPU自动解决对齐问题,在X64中CPU也会处理对齐问题,但是有性能消耗,但是对于IPF则CPU没有处理数据的对齐问题,所以
如果程序中没有处理,则会导致程序Crash。所以最后是我们在64编程中程序处理对齐问题,在程序中使用__aligned_malloc,这样也更有
利于在不同的64位架够间的移植。
6 优化方案
建议使用编译器的优化选项来优化64程序:whole program optimization ,profile-guided optimization.
三 总结
对于C++的64位移植,主要的问题就是指针的截断和数据的对齐,希望从现在开始我们就养成良好的习惯,使用动态指针类型,和程序处理数据的对齐问题,这样更有利于程序的64位移植。
转载地址:http://www.cnblogs.com/taoxu0903/archive/2009/04/26/1444042.html
DWORD_PTR的定义是, 这个类型至少可以确保放得下DWORD并且确保放得下一个指针。 DWORD的长度是固定得32位, 而指针的长度是跟硬件、系统、编译器什么的有关系的。 所以如果 你是在做32位程序,那么 DWORD_PTR就跟DWORD是一回事。如果你是在做64位程序,那么 DWORD_PTR 是64位的, 而DWORD永远是32位。乘此机会,找到一篇博文,转载过来研究研究。
主要是两个问题:指针截断和数据对齐。C/C++移植的问题1 新的数据类型和函数
1)固定精度:(跟X86或X64无关)
Term | Description |
---|---|
DWORD32 | 32-bit unsigned integer |
DWORD64 | 64-bit unsigned integer |
INT32 | 32-bit signed integer |
INT64 | 64-bit signed integer |
LONG32 | 32-bit signed integer |
LONG64 | 64-bit signed integer |
UINT32 | Unsigned INT32 |
UINT64 | Unsigned INT64 |
ULONG32 | Unsigned LONG32 |
ULONG64 | Unsigned LONG64 |
Term | Description |
---|---|
DWORD_PTR | Unsigned long type for pointer precision. |
HALF_PTR | Half the size of a pointer. Use within a structure that contains a pointer and two small fields. |
INT_PTR | Signed integer type for pointer precision. |
LONG_PTR | Signed long type for pointer precision. |
SIZE_T | The maximum number of bytes to which a pointer can refer. Use for a count that must span the full range of a pointer. |
SSIZE_T | Signed SIZE_T. |
UHALF_PTR | Unsigned HALF_PTR. |
UINT_PTR | Unsigned INT_PTR. |
ULONG_PTR | Unsigned LONG_PTR. |
Term | Description |
---|---|
POINTER_32 | A 32-bit pointer. On 32-bit Windows, this is a native pointer. On 64-bit Windows, this is a truncated 64-bit pointer. |
POINTER_64 | A 64-bit pointer. On 64-bit Windows, this is a native pointer. On 32-bit Windows, this is a sign-extended 32-bit pointer.Note that it is not safe to assume the state of the high pointer bit. |
[MSDN]An int and a long are
32-bit values on 64-bit Windows operating systems. For programs that you
plan to compile for 64-bit platforms, you should be careful not to
assign pointers to 32-bit variables. Pointers are 64-bit on 64-bit
platforms, and you will truncate the pointer value if you assign it to a
32-bit variable.在以前的32位系统中,指针的为32位,在新的64位系统中指针为64位,这样的话,我们以前编
程中常用的指针与int或long等的直接转化,放在新的64位的系统中就会出错,指针高位的值就会丢失,从而产生错误。例如下面的2行代码,在32位上
正确,但是在64位上就会发生指针截断,出现错误:
下面是我们使用新的动态数据类型,从而实现不用修改代码,直接在32位和64位上直接编译:
3 虚拟地址空间 (解决方法:在64位的指针中只不使用高32位,也就等于原来32位中的32位指针了)
在
32位的系统中,一共可以是用的内存为4G,但是对于用户的应用一般只可以使用2G,其他的2G为系统使用,当然你也可以打开3G的开关,这样的话最多就
能使用3G.对于高精度的浮点运算,高强度的数据库处理等,就需要更大的内存,这时候64位给我们带来了福音,在64位上我们最多可以使用16T的内存,
这样就大大提高了性能。但是对于一些没有使用到超过2G的内存,但当中却大量的使用了指针与整型等的强制转化的应用程序,我们可以使用一种简单的方法,使
用编译器的开关VBS:/Largeadressaware:no,使32位的程序移植到64位上。但是这种简单的移植方法,会带来一些弊端:如果被真的
64位所调用,就有可能真的产生指针的截断,同时也没有解决对齐问题和大内存的使用问题。
4 数据类型对齐和补齐
由于对 于不同的cpu架够有不同的数据对齐策列,而且数据的对齐也影响程序的性能和正确性。常用的2个宏:TYPE_ALIGNMENT(type)和
FIELD_OFFSET(type,member)分别用来计算指定类型的对齐值和某复合变量中成员的偏移量。对于复合数据类型,采用递归的计算方法。
对于复合数据类型如果没有对齐,则补齐,保证结尾处地址是该复合数据类型的整数倍。(在C++中可以使用#Program()来设置对齐方式)
5 CPU架构与对齐意外
对
于我们以前的32位,CPU自动解决对齐问题,在X64中CPU也会处理对齐问题,但是有性能消耗,但是对于IPF则CPU没有处理数据的对齐问题,所以
如果程序中没有处理,则会导致程序Crash。所以最后是我们在64编程中程序处理对齐问题,在程序中使用__aligned_malloc,这样也更有
利于在不同的64位架够间的移植。
6 优化方案
建议使用编译器的优化选项来优化64程序:whole program optimization ,profile-guided optimization.
三 总结
对于C++的64位移植,主要的问题就是指针的截断和数据的对齐,希望从现在开始我们就养成良好的习惯,使用动态指针类型,和程序处理数据的对齐问题,这样更有利于程序的64位移植。
转载地址:http://www.cnblogs.com/taoxu0903/archive/2009/04/26/1444042.html
相关文章推荐
- 64位平台C/C++开发注意事项
- 64位平台C/C++开发注意事项
- windows平台上向64位移植c/c++的变量类型大小变化
- 【收藏】64位平台C/C++开发注意事项
- 64位和32位平台下C/C++结构内存对齐
- 64位系统vs2010平台下实现C++与matlab R2014混合编程方法示例
- 64位平台C/C++容易犯的错误
- 64位平台C/C++开发注意事项
- C#中调用c++的dll如何适应32位跟64位的平台
- 64位平台C/C++开发注意事项(转载)
- 64位平台C/C++开发注意事项
- 64位平台C/C++开发注意事项
- Object c/swift,java,c/c++在32位和64位各个平台上基本数据类型 所占有的字节数
- windows 平台下C/C++ 64位整形数输出
- 利用 WM_COPYDATA 消息 在 C# 和 传统C++应用之间传递数据时,64位平台的问题
- 64位平台C/C++开发注意事项
- .NET平台处理32位系统和64位系统的一点兼容性问题
- C++ 64位整型的跨平台处理
- 在Visual C++.NET平台上调用MYSQL的C API的方法
- WINX调查:您使用什么C++开发平台?