Questions regarding "C4312 Warning:" cast type "

This is the code I have:

HWND WebformCreate(HWND hParent, UINT id) { return CreateWindowEx(0, WEBFORM_CLASS, _T("about:blank"), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, 100, 100, hParent, (HMENU)id, GetModuleHandle(NULL), 0); } 

This is the warning I get:

 warning C4312: 'type cast' : conversion from 'UINT' to 'HMENU' of greater size 

Here are the questions I have:

  • Why does the compiler think it's a bad idea to use a larger type?
  • What is the best way to get rid of a warning? (I do not want to turn it off.)
  • The double type is performed as follows: (HMENU)(UINT_PTR)id gets rid of the warning. Why / how?
  • Disabling "Detection of 64-bit portability problems" (Wp64) also eliminates the warning. Why is wp64 outdated? Should I have this?
+6
c ++ 64bit winapi
source share
3 answers

You start a 32-bit UINT with a 64-bit pointer. This is suicide - you are trying to point to something, but forgot half of this place! You absolutely SHOULD take UINT_PTR. When you point to an int pointer, the behavior will only be OK if the int is the same size as the pointer. This is also the end of your access violation application environment.

Edit:
Why does the compiler consider it a bad idea to distinguish a larger font?
RE above

What is the best way to get rid of a warning? (I do not want to turn it off.)
Solve the problem of. This code will almost certainly be instacrash.

Doing a double type like this: (HMENU) (UINT_PTR) id gets rid of the warning. Why / how?
This is because the excellent match UINT UINT_PTR - UINT_PTR is just an integral type, there is no data loss.

Disabling "Detect 64-bit portability problems" (Wp64) also resolves the warning. Why is wp64 outdated? Should I use it?
It is out of date, because in fact I can’t remember why. I think this is warning too easy. But for the main "Don't throw integer types and pointers", you should definitely leave it.

+2
source share

The type that is hidden behind the name HMENU is actually a pointer type. The compiler tells you that a shell of a smaller integer type with a larger pointer type does not make sense, since the resulting pointer value will be "incomplete", that is, bits of a higher order if the pointer value is filled with zeros. The latter makes very little sense with pointer types.

In your particular case, this is safe, since this HMENU value should not really be a pointer pointing anywhere. However, the compiler does not know this, so it issues a warning. Use a larger integer type as an intermediate type in the listing, and the warning should disappear (you assumed that you yourself), since in this case you make two casts: a smaller integer with a large integer, and then a larger integer with a pointer . A smaller integer with a large integer is arithmetic casting, for which it makes sense to fill bits of a higher order with zeros (the presented value does not change), so there will be no warnings for it.

+10
source share

Why does the compiler think it's a bad idea to use a larger type?

Listing between types of different sizes is usually a problematic operation because the source type may not display all the values ​​needed for the purpose.

What is the best way to get rid of a warning? (I do not want to turn it off.)

I would say use HMENU everywhere and declare your function as

 HWND WebformCreate(HWND hParent, HMENU id) 

Doing a double type like this: (HMENU) (UINT_PTR) id gets rid of the warning. Why / how?

UINT_PTR is an integer type large enough to hold all pointer values, so the warnings go away.

HMENU - pointer type. This does not mean that the HMENU value is actually a pointer, but it is a hack that prevents you from implicitly mixing, for example. HMENU and HWND (because HMENU and HWND are something like struct _hMENU* and struct _hWND* , respectively, which are incompatible, whereas UINT will be).

+2
source share

All Articles