The following results don't make any sense to me. It looks like a negative offset is cast to unsigned before addition or subtraction are performed.
double[] x = new double[1000];
int i = 1; // for the overflow it makes no difference if it is long, int or short
int j = -1;
unsafe
{
fixed (double* px = x)
{
double* opx = px+500; // = 0x33E64B8
//unchecked
//{
double* opx1 = opx+i; // = 0x33E64C0
double* opx2 = opx-i; // = 0x33E64B0
double* opx3 = opx+j; // = 0x33E64B0 if unchecked; throws overflow exception if checked
double* opx4 = opx-j; // = 0x33E64C0 if unchecked; throws overflow exception if checked
//}
}
}
Although it might seem strange to use negative offsets, there are use cases for it. In my case it was reflecting boundary conditions in a two-dimensional array.
Of course, the overflow doesn't hurt too much because I can either use unchecked or move the sign of the value to the operation by inverting and applying it to the modulus of the operand.
But this behaviour seems undocumented. According to MSDN I don't expect negative offsets to be problematic:
You can add a value n of type int, uint, long, or ulong to a pointer, p,of any type except void*. The result p+n is the pointer resulting from adding n * sizeof(p) to the address of p. Similarly, p-n is the pointer resulting from subtracting n * sizeof(p) from the address of p.
checked
block to be sure – Longdistanceopx
,j
andopx + j
or debug it. – Mildred