This is a default HashKey function in MFC's CMap class.
AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
{
// default identity hash - works for most primitive values
return ((UINT)(void*)(DWORD)key) >> 4;
}
My question is why the type casting (DWORD) and (void*) are needed?. I guess the (DWORD) may have some relationship with compatibility affairs for 16-bit machines. But I'm confused about the void*.
Casting to void is used to suppress compiler warnings. The Standard says in §5.2. 9/4 says, Any expression can be explicitly converted to type “cv void.” The expression value is discarded. Follow this answer to receive notifications.
LPBYTE. A pointer to a BYTE. This type is declared in WinDef.
LPDWORD is just a typedef for DWORD* and when a Windows SDK function parameter is a "LPsomething" you generally need to pass a pointer to a "something" (except for the LP[C][W]STR string types).
LPVOID data types are defined as being a "pointer to a void object". This may seem strange to some people, but the ANSI-C standard allows for generic pointers to be defined as "void*" types. This means that LPVOID pointers can be used to point to any type of object, without creating a compiler error.
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);
}
That's what that function looks like today. Your version came from a very old version of MFC, old enough to still support 16-bit programs. MFC was first released in 1992, the days of Windows version 3. MFC versions 1.0 through 2.5 supported 16-bit targets. The current version of the function is good for 32-bit and 64-bit code.
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.
The cast to DWORD
will reduce the size to a DWORD
.
The cast to void*
will reduce the size to a pointer.
There is not much more that can be inferred from these casts, and in a realistic environment it's overkill, but it's fair to expect an optimizing compiler not to do any unnecessary work through these conversions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With