I have a class that has two int
fields x
and y
, and a method Increment
that increments both of these fields by dx
and dy
respectively. I would like to prevent the state of my class to become corrupted by silent arithmetic overflows (which would result to x
or y
or both becoming negative), so I am explicitly incrementing the fields in a checked
block:
class MyClass
{
private int x;
private int y;
public void Increment(int dx, int dy)
{
checked { x += dx; y += dy; }
}
}
This should ensure that in case of arithmetic overflow the caller will receive an OverflowException
, and the state of my class will remain intact. But then I realized that an arithmetic overflow could occur in the increment of y
, after the x
has already successfully incremented, resulting to a different type of state corruption, which is not less disruptive than the first. So I changed the implementation of the Increment
method like this:
public void Increment2(int dx, int dy)
{
int x2, y2;
checked { x2 = x + dx; y2 = y + dy; }
x = x2; y = y2;
}
This seems like a logical solution to the problem, but now I am concerned that the compiler could "optimize" my carefully crafted implementation, and reorder the instructions in a way that would allow the x
assignment to occur before the y + dy
addition, resulting again to state corruption. I would like to ask if, according to the C# specification, this undesirable scenario is possible.
I am also considering removing the checked
keyword, and instead compiling my project with the "Check for arithmetic overflow" option enabled (<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
). Could this make any difference, regarding a possible reordering of the instructions inside the Increment
method?
Update: a more succinct arithmetic-overflow-safe implementation is possible by using tuple deconstruction. Is this version any different (less safe) than the verbose implementation?
public void Increment3(int dx, int dy)
{
(x, y) = checked((x + dx, y + dy));
}
Clarification: The MyClass
is intended to be used in a single-threaded application. Thread-safety is not a concern (I know that it's not thread-safe, but it doesn't matter).