Handling integer overflow is a common task, but what's the best way to handle it in C#? Is there some syntactic sugar to make it simpler than with other languages? Or is this really the best way?
int x = foo(); int test = x * common; if(test / common != x) Console.WriteLine("oh noes!"); else Console.WriteLine("safe!");
An integer overflow occurs when you attempt to store inside an integer variable a value that is larger than the maximum value the variable can hold. The C standard defines this situation as undefined behavior (meaning that anything might happen).
By far the most common practice regarding integer overflows is that programmers are expected to know that the issue exists, to watch for cases where they might happen, and to make the appropriate checks or rearrange the math so that overflows won't happen, things like doing a * (b / c) rather than (a * b) / c .
Avoidance. By allocating variables with data types that are large enough to contain all values that may possibly be computed and stored in them, it is always possible to avoid overflow.
scanf() is tough to limit. It may not set errno on overflow. Code can limit the number of char to say 9. That's a first step but one can not enter values like "1000000000" or "00000000000000001".
I haven't needed to use this often, but you can use the checked keyword:
int x = foo(); int test = checked(x * common);
Will result in a runtime exception if overflows. From MSDN:
In a checked context, if an expression produces a value that is outside the range of the destination type, the result depends on whether the expression is constant or non-constant. Constant expressions cause compile time errors, while non-constant expressions are evaluated at run time and raise exceptions.
I should also point out that there is another C# keyword, unchecked
, which of course does the opposite of checked
and ignores overflows. You might wonder when you'd ever use unchecked
since it appears to be the default behavior. Well, there is a C# compiler option that defines how expressions outside of checked
and unchecked
are handled: /checked. You can set it under the advanced build settings of your project.
If you have a lot of expressions that need to be checked, the simplest thing to do would actually be to set the /checked
build option. Then any expression that overflows, unless wrapped in unchecked
, would result in a runtime exception.
Try the following
int x = foo(); try { int test = checked (x * common); Console.WriteLine("safe!"); } catch (OverflowException) { Console.WriteLine("oh noes!"); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With