views:

99

answers:

3

So I am trying to port 32 bit to 64 bit.

I have turned on the VS2008 flag for detecting problems with 64 bit.

I am trying following:

char * pList = (char *)uiTmp);

warning C4312: 'type cast' : conversion from 'unsigned int' to 'char *' of greater size

Disregard the code itself. This is also true for any pointer, because 64 bit pointer is greater than 32 bit unsigned int or int for that purpose.

Given that you have to cast smaller type to greater how would you go about doing it so it correctly on both 32/64 bit systems

+3  A: 

This is not a warning you can ignore, it will bomb in 64-bit code. An unsigned int cannot store a pointer. There's no magic cast that will make this work.

Review your code and rethink storing pointer values in an unsigned int. It should probably be a void*. If you #include <windows.h> then you can use UINT_PTR.

Hans Passant
On any environment having `stdint.h` (which is standard in C99, though sadly not supported by MSVC++), use `intptr_t` or `uintptr_t`. These are defined to be integer types wide enough to hold a pointer.
j_random_hacker
I'm curious why this got accepted, given that it answers a totally different question. The problem was that he was trying to store an unsigned int into a pointer, not the other way around. Physically, it should fit just fine with 32 bits to spare.
T.E.D.
This answer was obviously assuming that uiTmp was supposed to contain a pointer value, assigned somewhere else. Another interpretation would make little sense. Well, to me and the OP anyway.
Hans Passant
+1  A: 

Main points to watch out for when moving from 32 to 64 bit platform:

  • sizeof(int) != sizeof(void*) anymore. Audit all occurrences of casting integer to pointer and back.
  • Structure alignment and sizes change. For example the following is packed into 8 bytes on 32 bit, but has a hole in the middle and takes 16 bytes on 64 bit:
    struct list
    {
        int          val_;
        struct list* next_;
    };
  • Implicit assumptions for IPC and network communications will bite you.

One specific issue I came across several times was that on 32-bit Linux repeated calls to vprintf(3) without re-initializing va_list with va_end/va_start silently works (while being undefined behavior), but loudly bombs on 64-bit due to different calling convention.

Nikolai N Fetissov
A: 

I had the same problem. In my case the code was trying to generate a random HANDLE using rand() which returns a 32-bit value. (Why did it want a random handle value? Don't ask...)

What I found works to appease the compiler was the following:

char * pList = (char *)(0) + uiTmp; 

This should work OK if your system uses 32-bit or 64-bit pointers. Of course you might not want to be using 32-bit integers on a 64-bit platform, depending on what exactly your code is doing.

T.E.D.