55

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!");
2
  • 5
    best way is to prevent in first place Commented Jun 2, 2010 at 4:14
  • 12
    Sure, but that's a different question from the one presented here. Handling it and preventing it are seperate (related of course) discussions. Commented Jun 2, 2010 at 4:16

6 Answers 6

122

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Why is the default behavior is unchecked? Is there any performance concerns on using checked?
@KFL "Because checking for overflow takes time, the use of unchecked code in situations where there is no danger of overflow might improve performance. However, if overflow is a possibility, a checked environment should be used." See msdn.microsoft.com/en-us/library/a569z7k8.aspx. I also believe that the default is unchecked because it parallels the C / C++ behavior.
There are cases where overflow is useful, for instance the TCP sequence number. An unsigned int just wraps around to zero, so all that's needed is the increment operator.
Does unchecked produce same results in case of overflow on all machines??
Updated url reference for 'checked' - msdn.microsoft.com/en-us/library/74b4xzyw(v=vs.140).aspx
|
22

Try the following

int x = foo();
try {
  int test = checked (x * common);
  Console.WriteLine("safe!");
} catch (OverflowException) {
  Console.WriteLine("oh noes!");
}

Comments

8

The best way is as Micheal Said - use Checked keyword. This can be done as :

int x = int.MaxValue;
try   
{
    checked
    {
        int test = x * 2;
        Console.WriteLine("No Overflow!");
    }
}
catch (OverflowException ex)
{
   Console.WriteLine("Overflow Exception caught as: " + ex.ToString());
}

1 Comment

You need to format your code (insert 4 spaces prior to it and the site will automatically pick up the formatting and syntax highlighting.
6

Sometimes, the simplest way is the best way. I can't think a better way to write what you wrote, but you can short it to:

int x = foo();

if ((x * common) / common != x)
    Console.WriteLine("oh noes!");
else
    Console.WriteLine("safe!");

Note that I didn't remove the x variable because it'd be foolish to call the foo() three times.

3 Comments

Now I wonder if the compiler would ever optimize that expression away entirely?
USefull, unless of course you are planning on using the result (x*common), in that case your shortening would require the calculation to be done twice ...
What if common == 0?
5

Old thread, but I just ran into this. I didn't want to use exceptions. What I ended up with was:

long a = (long)b * (long)c;
if(a>int.MaxValue || a<int.MinValue)
    do whatever you want with the overflow
return((int)a);

2 Comments

This won't work. int.MaxValue + 1 gives you -2147483648 or int.MinValue. so a can never be larger than MaxValue or smaller than MinValue. Think of numbers as a line like this: -2147483648, -2147483647, ... 0 ... 2147483646, 2147483647 when you go over the max value, it flows back to the smallest.
you missed the fact that he/she converted to long before checking against the bounds of the int. so it would work as long it doesnt overflow the long.
0

So, I ran into this far after the fact, and it mostly answered my question, but for my particular case (in the event anyone else has the same requirements), I wanted anything that would overflow the positive value of a signed int to just settle at int.MaxValue:

int x = int.MaxValue - 3;
int someval = foo();

try
{
   x += someval;
}

catch (OverflowException)
{
   x = int.MaxValue;
}

1 Comment

The exception wouldn't get thrown unless you compile with /checked, or use the checked keyword, correct?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.