引自http://msdn.microsoft.com/en-us/library/windows/desktop/aa384242%28v=vs.85%29.aspx
在适当的地方使用UINT_PTR和INT_PTR(如果您不确定的话) 无论它们是否必需,使用它们都没有害处 案件)。不要将指针转换为ULONG,LONG,INT,UINT类型, 或者DWORD。
我可以安全地假设在现有的32位Codeline中将所有引用的DWORD转换为UNIT_PTR是安全的,没有任何副作用吗?
是否还有其他建议的指导方针来移植代码行中引用了DWORD的32位代码?
答案 0 :(得分:6)
这太粗糙了。只需让编译器为您完成工作,启用警告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。
答案 1 :(得分:2)
如果您计划在变量中存储指针(包括各种形式的INT_PTR
),则只需使用UINT_PTR
或HANDLE
。如果它只是一个常规的积分值,那么无关紧要。
如果您将所有DWORD
盲目翻译为UINT_PTR
,我希望您至少会收到“尝试将较大类型存储在较小类型中”的警告。 [也就是说,在编译64位代码时,如在32位代码中,类型UINT_PTR
与DWORD
相同,因此在这种情况下您可能不会收到任何警告]。
答案 2 :(得分:1)
添加@MatsPetersson答案 -
DWORD
被广泛用于保存地址的原因是它与32位体系结构上的指针大小相匹配。
最佳做法是对包含地址的变量使用专用类型。这就是UINT_PTR
& INT_PTR
用于 - 它们对于32位和64位目标都是正确的,因为它们的定义是根据编译目标正确设置的。实际上,您可以浏览MS标头并亲自查看这些类型对应的实际基元类型。
每当变量用于地址以外的数据时,应根据存储的数据定义实际类型,通常不依赖于底层计算机体系结构 - DWORD
将保持DWORD
,{{ 1}}将保留WORD
等。