澄清:移植32到64位

问题描述:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa384242%28v=vs.85%29.aspx澄清:移植32到64位

使用UINT_PTR和INT_PTR在适当情况下(如果你不确定 无论他们是必需的,但更是在短短的 情况下使用它们没有伤害)报价。不要将指针指向ULONG,LONG,INT,UINT, 或DWORD类型。

我可以安全地假设在现有的32位Codeline中将所有引用的DWORD转换为UNIT_PTR是安全的,没有任何副作用?

是否还有其他推荐的指南来移植引用DWORD的32位代码?

+0

等等,不,你误解了。不要将所有'DWORD'转换为'UINT_PTR'! – 2013-02-26 19:04:58

+0

@MooingDuck:你为什么这么认为?你能解释一下吗? – Abhijit 2013-02-26 19:11:22

+4

(1)只有在需要将指针存储在整数类型变量中时才使用'UINT_PTR'。否则使用整数或指针。 (2)'UINT_PTR'有时候会是32位,有时候是64位,大多数情况下,你不需要它。 (3)由于它破坏了二进制的兼容性和可移植性,这取决于你如何完成你的IO,它可能会使你的数据不可移植。 – 2013-02-26 19:19:38

这太粗暴了。只要让编译器为你做好工作,启用警告4302,它会告诉你指针值何时被截断。将#pragma放在一个合适的位置,预编译的头文件将是理想的。或者指定/we4302编译器选项。

#pragma warning(default:4302) 

int main() 
{ 
    int* p = 0; 
    long bad = (long)p; // C4302: 'type cast' : truncation from int* to long 
    return 0; 
} 

的/ Wp64编译选项可以是有用的,对于一嗅,无论如何,但它has problems

+0

+1:'这太粗暴了',但这听起来对我来说是最实际的解决方案 – Abhijit 2013-02-26 19:53:35

+0

你的回答是最实际的。我在我的构建系统中添加/ we4302,现在正在努力修复遗留的罪恶 – Abhijit 2013-03-02 15:25:37

如果您打算在变量(包括各种形式的HANDLE)中存储指针,则只需要使用INT_PTRUINT_PTR。如果它只是一个常规的整数值,那么它就没有关系。

如果您将所有DWORD盲目翻译为UINT_PTR,我预计至少会出现一些“尝试以较小类型存储较大类型”的警告。 [也就是说,当你编译64位代码时,与32位代码类似,UINT_PTR类型与DWORD相同,所以在这种情况下你可能不会收到任何警告]。

+0

所以我可以安全地得出结论,我可以将所有引用的DWORD转换为UINIT_PTR? – Abhijit 2013-02-26 19:03:33

+0

我认为这就是我的回答:你不应该盲目地将每个DWORD转换为'UINT_PTR',因为有可能出现'DWORD'正确的情况。当然,没有看到你的代码,我不知道,因为我不知道你在用什么'DWORD'。但是,在几乎所有情况下,DWORD都不用于存储指针,所以如果没有其他指针,则会为您的数据使用更多的空间。 – 2013-02-26 19:06:17

+0

'所以如果没有其他的东西,你会使用更多的空间来存储你的数据',是的,我明白了。但正如你所说,除了存储指针之外,DWORD还有许多用途,如果我将所有DWORD盲目地转换为UNIT_PTR,除了使用更多空间之外,还会有其他含义吗? – Abhijit 2013-02-26 19:10:58

上添加@MatsPetersson答案 -

原因DWORD被广泛用于保存的地址是它在32位架构的指针大小相匹配。

最佳做法是为变量保存地址使用专用类型。这就是UINT_PTR & INT_PTR适用于 - 它们对于32位和64位目标都是正确的,因为它们的定义根据编译目标正确设置。实际上,您可以浏览MS标题,并查看这些类型所对应的实际基本类型。

每当可变用于除地址以外的数据,实际的类型应根据所存储的数据来定义,并且通常不会依赖于底层的计算机体系结构 - DWORD仍将DWORDWORD仍将WORD

+1

它当然不再被广泛使用。这个*是一个错误。 – Puppy 2013-02-26 19:23:54

+0

@DeadMG什么是不广泛使用?什么是*和什么是错误? – SomeWittyUsername 2013-02-26 19:24:49