5

这是 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*感到困惑。

4

3 回答 3

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 位代码。

In 16-bit code, one option to select was the memory model. You could pick cheap 16-bit near pointers or expensive 32-bit far pointers. So the extra void* cast trims the value to the memory model size.

于 2013-02-25T13:28:21.297 回答
2

强制转换为DWORD将大小减小到DWORD.

强制转换void*会将大小减小为指针。

从这些转换中无法推断出更多的东西,在现实环境中它是矫枉过正的,但期望优化编译器不会通过这些转换做任何不必要的工作是公平的。

于 2013-02-25T04:47:36.363 回答
1

这里需要转换为DWORD(Double Word) 来告诉 CPU 他需要移动哪些字节,在这种情况下他只移动DWORD位。(void*)转换是使您只需移动 4 次的数字到一个指针(转换为通用地址大小)。

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

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

于 2013-02-25T07:16:11.817 回答