Unicorn with delicious cookie
Our website uses cookies to enhance your browsing experience.
Accept
to the top
>
>
>
V204. Explicit conversion from...
menu mobile close menu
Additional information
toggle menu Contents

V204. Explicit conversion from 32-bit integer type to pointer type.

Jun 13 2012

The analyzer has detected explicit type casting of a 32-bit integer type to a pointer type. The V201 diagnostic rule used to detect such behavior, but explicit conversion of the int type to a pointer is much more dangerous than conversion of 'int' to intptr_t. So, a separate diagnostic rule to search for explicit type conversions when handling pointers has been created.

Here is a sample of incorrect code.

int n;
float *ptr;
...
ptr = (float *)(n);

The int type is 4 bytes in a 64-bit program, so it cannot store a pointer of 8 bytes. Type casting, as shown in the example above, usually indicates an error.

Such errors are particularly problematic as they may not manifest immediately. A program can store pointers in 32-bit variables and work correctly for some time, as long as all the objects created in the program are located at low-order addresses in memory.

If you need to store a pointer in an integer variable for some reason, use memsize types like size_t, ptrdiff_t, intptr_t, or uintptr_t.

This is the correct code:

intptr_t n;
float *ptr;
...
ptr = (float *)(n);

However, there is a specific case when you may store a pointer in 32-bit types—handles, which are used in Windows to work with various system objects. Here are examples of such types: HANDLE, HWND, HMENU, HPALETTE, HBITMAP, etc. They are actually pointers. For instance, HANDLE is defined in header files as typedef void *HANDLE;.

Although descriptors are 64-bit pointers, they use only 32-bit low-order pointers for better compatibility (for example, to enable interaction between 32-bit and 64-bit processes).. You can find more details in "Microsoft Interface Definition Language (MIDL): 64-Bit Porting Guide" (USER and GDI handles are sign extended 32b values).

Such pointers can be stored in 32-bit data types (for instance, int, DWORD). Special functions are used to cast such pointers to 32-bit types and vice versa:

void            * Handle64ToHandle( const void * POINTER_64 h ) 
void * POINTER_64 HandleToHandle64( const void *h )
long              HandleToLong    ( const void *h )
unsigned long     HandleToUlong   ( const void *h )
void            * IntToPtr        ( const int i )
void            * LongToHandle    ( const long h )
void            * LongToPtr       ( const long l )
void            * Ptr64ToPtr      ( const void * POINTER_64 p )
int               PtrToInt        ( const void *p )
long              PtrToLong       ( const void *p )
void * POINTER_64 PtrToPtr64      ( const void *p )
short             PtrToShort      ( const void *p )
unsigned int      PtrToUint       ( const void *p )
unsigned long     PtrToUlong      ( const void *p )
unsigned short    PtrToUshort     ( const void *p )
void            * UIntToPtr       ( const unsigned int ui )
void            * ULongToPtr      ( const unsigned long ul )