Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why IntPtr.ToInt32 throws OverflowException in 64 bit mode and Explicit(IntPtr to Int32) doesn't

Tags:

clr

64-bit

intptr

The operator's description on MSDN has a remark:

An exception is only thrown if the value of value requires more bits than the current platform supports.

while ToInt32's description doesn't so I suppose the title is not entirely correct(for brevity),

a more correct question would be: "Why IntPtr.ToInt32 throws OverflowException in 64 bit mode for values that fit in Int32 and Explicit(IntPtr to Int32) doesn't"

In decompiled IntPtr ToInt32 and the operator look very similar:

public static explicit operator int(IntPtr value)
{
  return (int) value.m_value;
}

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public unsafe int ToInt32()
{
  return (int) this.m_value;
}

I wonder what makes ToInt32 throw the exception, is it the unsafe keyword?

like image 442
axk Avatar asked Jun 25 '12 15:06

axk


1 Answers

Your disassembler can't do a proper job here, mscorlib.dll is special. It is not an AnyCPU assembly, Microsoft builds and ships different versions of it, based on the processor architecture. I'd recommend you use the Reference Source, you'll get the original source code. Which looks like this:

    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    public unsafe int ToInt32() {
        #if WIN32
            return (int)m_value;
        #else
            long l = (long)m_value;
            return checked((int)l);
        #endif
    }

It is the checked keyword that provides the OverflowException.

like image 142
Hans Passant Avatar answered Sep 27 '22 16:09

Hans Passant