C # (.NET Frameworks) –When I cast an IntPtr with a value of 0x80000000 or more to uint, an OverflowException occurs even though the value fits in uint, so I analyzed it.

1 minute read


When I was using the Windows API [https://qiita.com/kob58im/items/0273632e96afceca7d0a), I encountered the phenomenon of the title, so I searched for the cause.

Experimental code

using System;

class CastTest
    static void Main(string[] args)
        IntPtr t1 = new IntPtr(0x7FFFFFFFu);
        IntPtr t2 = new IntPtr(0x80000000u);

            uint tmp = 0x80000000u;
            uint t1Cast = (uint)t1;
            uint t2Cast = (uint)t2; //An exception occurs here
        catch(OverflowException e){

Execution result

```Execution result

System.OverflowException:An overflow occurred as a result of an arithmetic operation.
Location CastTest.Main(String[] args)

# Cause-Internally casting to int

 When I checked the compiled code of the process corresponding to ʻuint t2Cast = (uint) t2; `in ildasm, it is as follows.
 You are casting to <b> int. .. </b>

call int32 [mscorlib]System.IntPtr::op_Explicit(native int)

 Looking at the above method in ILSpy, it is as follows. <b> It is politely marked with `checked`. </b>, so throw an overflow exception.


public unsafe static explicit operator int(IntPtr value)
	long num = (long)value.m_value;
	return checked((int)num);

Workaround (provisional)

For the time being, go through the cast to long type.
(If you are called from among the valid checked, you will probably encounter the same thing if the 63rd bit is standing …)

By the way, if you look at what seems to be a method cast to long with ILSpy,

public unsafe static explicit operator long(IntPtr value)
	return (long)value.m_value;

It has become.