7

How can I find out, using C# code, if I'm in a checked context or not, without causing/catching an OverflowException, with the performance penalty that incurs?

Evgeniy Berezovsky
  • 18,571
  • 13
  • 82
  • 156
  • Is there a practical reason for needing to know? If you need to be in one other the other context, that's what the `checked` and `unchecked` operators are for. If you don't need to be in one or the other, why would you care to know? – Preston Guillot Jan 22 '15 at 01:46
  • 1
    I am afraid causing/catching `OverflowException` is by far the easiest way, if not the only way. – kennyzx Jan 22 '15 at 01:49
  • @PrestonGuillot (Say) I want to [implement an arithmetic operation](http://stackoverflow.com/q/28059655/709537) that only throws on arithmetic overflows if inside `checked`. – Evgeniy Berezovsky Jan 22 '15 at 01:50
  • @EugeneBeresovsky I wasn't aware of the undefined corner case called out from the linked answer, intestesting. For what's it's worth, the undefined case remains in the C# 5.0 spec as well. – Preston Guillot Jan 22 '15 at 02:02

1 Answers1

6

The only difference between a block that is checked vs unchecked are the IL instructions generated by the compiler for basic value type arithmetic operations. In other words, there is no observable difference between the following:

checked {
  myType.CallSomeMethod();
}

and

myType.CallSomeMethod();

But lets say that there is an arithmetic operation, such as adding two integers. You would need to get the IL instructions for the method and check if the instructions around your method call are checked, and even that is far from bullet proof. You cannot tell if your custom operation is actually within the checked block, or just surrounded by checked blocks that it is not inside.

Even catching an exception will not work, since you cannot differentiate between these two cases:

checked {
  int a = (Some expression that overflows);
  myType.CallSomeMethod();
}

and

checked {
  int a = (Some expression that overflows);
}
myType.CallSomeMethod();

This is probably part of why the Decimal type does not attempt to detect checked vs unchecked and instead always throws OverflowException.

Chris Pitman
  • 12,990
  • 3
  • 41
  • 56