Is IntPtr(long) truncating?

The short answer is: No, not when it matters

A colleague and I were discussing a particular scenario around IntPtr,PInvoke and 64 bit correctness.  Eventually our discussion lead us to the IntPtr constructor which takes a long.  To my surprise the code for the constructor is the following.

public unsafe IntPtr (long value) { this.m_value = (void*) ((int) value); }

The problem is long value is arbitrarily truncated to an int.  This has the effect of essentially losing any address over the 4 GB range (in other words, no 64 bit addresses).  This much to big of a hole to actually be the real behavior so I decided to see if it was a bug in the disassembler.  I was using .Net Reflector so I switched to IL mode. 

     L_0000: ldarg.0 
    L_0001: ldarg.1 
    L_0002: conv.ovf.i4 
    L_0003: conv.i 
    L_0004: stfld void* System.IntPtr::m_value
    L_0009: ret 

This confirmed it is indeed truncating the value (and doing an overflow check to boot). But wait, mscorlib.dll is a processor specific DLL so perhaps this is just a 32 bit OS thing.  I switched over to a 64 bit machine, fired up Reflctor and found to my dismay that it had the exact same code. 

After a few minutes I thought to open up task manager and to my surprise reflector was running in a WoW64 bit process.  This meant it was still loading up the 32 bit version of mscorlib.dll.  Next I fired up ildasm, loaded up a 64 bit mscorlib and confirmed that the code will not truncate on 64 bit machines.

   IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  conv.u
  IL_0003:  stfld      void* System.IntPtr::m_value
  IL_0008:  ret

The conv.u code is a conversion to unsigned native platform int. On a 64 bit machine this will be an unsigned 8 byte number(see OpCodes.Conv_U for more details). 

So what does this mean for the developer.  Essentially IntPtr(long) will do the right thing independently of the platform a developer is using.  On a 32 bit platform it will (correctly) throw exceptions if a non-4GB address is passed in.  In 64 bit land it will essentially do nothing and rely on the programmer to give correct addresses.