I'm trying to remove a c-style cast from some code I'm working on, and I have concerns about the only alternative.
The original code was:
WPARAM param = (WPARAM)(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
If I use a static cast:
WPARAM param = static_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
I get the error, 'static_cast' : cannot convert from 'HWND' to 'WPARAM', because there's no valid conversion between the underlying types. This leaves me with "the devil's option":
WPARAM param = reinterpret_cast<WPARAM>(GetDlgItem(IDC_WORKFLOW).m_hWnd);
this->PostMessage(WM_NEXTDLGCTL, param, TRUE);
As I understand it, if a static_cast is impossible, and this isn't related to constness, the C-cast must be doing a reinterpret_cast anyway, which means that the underlying code must be casting back, which means this is safe (point 3 in remarks). But I'd like to confirm this, before just changing the code.
Is this cast safe in this specific instance, and how do I confirm this? If not, what is the alternative?
It is safe, because WPARAM
is defined as:
typedef UINT_PTR WPARAM;
and _PTR suffix means the type is big enough to hold a pointer.
while HWND is:
typedef HANDLE HWND;
where HANDLE is:
typedef void *HANDLE;
so size of void* and UINT_PTR are always the same. If you would store it in 64bit application and try read in 32 bit application, then you would get in trouble.
if you are still concenred if that is safe to do such casts, you can search Visual Studio sources (in C:\Program Files (x86)\Microsoft Visual Studio 8\ folder), and you will find lots of lines with reinterpret_cast<LPARAM>(...)
and reinterpret_cast<WPARAM>(...)
.