为什么需要类型铸件(UINT)(void *)(DWORD)?

时间:2013-02-25 04:31:56

标签: c++ c mfc casting

这是MFC的CMap类中的默认HashKey函数。

AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
{
  // default identity hash - works for most primitive values
  return ((UINT)(void*)(DWORD)key) >> 4;
}

我的问题是为什么需要输入(DWORD)(void *)?我猜(DWORD)可能与16位机器的兼容性事务有一些关系。但我对 void * 感到困惑。

3 个答案:

答案 0 :(得分:8)

template<class ARG_KEY>
AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
{
    // default identity hash - works for most primitive values
    return (DWORD)(((DWORD_PTR)key)>>4);
}

这就是今天的功能。您的版本来自一个非常旧版本的MFC,足以支持16位程序。 MFC于1992年首次发布,即Windows版本3的时代.MFC版本1.0到2.5支持16位目标。该函数的当前版本适用于32位和64位代码。

在16位代码中,一个选项是内存模型。您可以选择便宜的16位指针或昂贵的32位指针。因此额外的void * cast会将值修剪为内存模型大小。

答案 1 :(得分:2)

转换为DWORD会将尺寸缩小为DWORD

转换为void*会将大小缩小为指针。

从这些演员表中可以推断出更多的东西,并且在现实的环境中它是过度的,但是期望优化编译器不通过这些转换做任何不必要的工作是公平的。

答案 2 :(得分:1)

这里需要转换为DWORD(双字)以告诉CPU他需要移位哪些字节,在这种情况下他只移位DWORD位。(void*)转换是使你只需将4次移动到指针(转换为通用地址大小)。

OS *(32b系统或64b系统)之间的void *大小可能不同,因此您必须进行此转换。

(UINT)的最后一次转换是将指针强制转换为无符号整数,以便将内存地址作为数字。