Search code examples
c#intptr

IntPtr.ToInt32() throws excption on 64bit, but will IntPtrToInt64() throw on 32bit machine?


I have this code:

if (hnd == IntPtr.Zero || hnd.ToInt32() == -1)

hnd is an IntPtr

This throws OverflowException, so I modified it to

 if (hnd == IntPtr.Zero || hnd.ToInt64() == -1)

The documentation says ToInt32 can throw an exception, but ToInt64 can't(?).

  //
// Summary:
//     Converts the value of this instance to a 32-bit signed integer.
//
// Returns:
//     A 32-bit signed integer equal to the value of this instance.
//
// Exceptions:
//   T:System.OverflowException:
//     On a 64-bit platform, the value of this instance is too large or too small to
//     represent as a 32-bit signed integer.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SecuritySafeCritical]
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public int ToInt32();
//
// Summary:
//     Converts the value of this instance to a 64-bit signed integer.
//
// Returns:
//     A 64-bit signed integer equal to the value of this instance.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SecuritySafeCritical]
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public long ToInt64();

So the questions: Will hnd.ToInt64() will throw an exception on a 32bit machine or won't?


Solution

  • The documentation states that:

    An instance of this type is expected to be 32-bits on 32-bit hardware and operating systems, and 64-bits on 64-bit hardware and operating systems

    So:

    • On a 64-bit OS, IntPtr can go from Int64.MinValue to Int64.MaxValue. Obviously, this can throw an overflow when converted to an Int32 since the range is longer.
    • On a 32-bit OS, IntPtr can go from Int32.MinValue to Int32.MaxValue, so you can convert that to Int64 and Int32 since the value will always be inside the range.