Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why the type castings (UINT)(void*)(DWORD) are needed? [closed]

Tags:

c++

c

casting

mfc

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*.

like image 867
duleshi Avatar asked Feb 25 '13 04:02

duleshi


People also ask

What does casting to void do in C?

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.

What is Lpbyte?

LPBYTE. A pointer to a BYTE. This type is declared in WinDef.

What is Lpdword?

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).

What is Lpvoid?

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.


2 Answers

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.

like image 50
Hans Passant Avatar answered Oct 26 '22 07:10

Hans Passant


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.

like image 32
Drew Dormann Avatar answered Oct 26 '22 08:10

Drew Dormann