Is it possible (in C#) to cause a checked(...)
expression to have dynamic "scope" for the overflow checking? In other words, in the following example:
int add(int a, int b)
{
return a + b;
}
void test()
{
int max = int.MaxValue;
int with_call = checked(add(max, 1)); // does NOT cause OverflowException
int without_call = checked(max + 1); // DOES cause OverflowException
}
because in the expression checked(add(max, 1))
, a function call causes the overflow, no OverflowException
is thrown, even though there is an overflow during the dynamic extent of the checked(...)
expression.
Is there any way to cause both ways to evaluate int.MaxValue + 1
to throw an OverflowException
?
EDIT: Well, either tell me if there is a way, or give me a better way to do this (please).
The reason I think I need this is because I have code like:
void do_op(int a, int b, Action<int, int> forSmallInts, Action<long, long> forBigInts)
{
try
{
checked(forSmallInts(a, b));
}
catch (OverflowException)
{
forBigInts((long)a, (long)b);
}
}
...
do_op(n1, n2,
(int a, int b) => Console.WriteLine("int: " + (a + b)),
(long a, long b) => Console.WriteLine("long: " + (a + b)));
I want this to print int: ...
if a + b
is in the int
range, and long: ...
if the small-integer addition overflows. Is there a way to do this that is better than simply changing every single Action
(of which I have many)?
To be short, no it is not possible for checked blocks or expressions to have dynamic scope. If you want to apply this in the entirety of your code base you should look to adding it to your compiler options.
Checked expressions or checked blocks should be used where the operation is actually happening.