Search code examples
c#integer-overflowinterlockedinterlocked-increment

How do I check for overflow after an Interlocked.Increment in C#?


What is the correct way to check for an overflow after a call to Interlocked.Increment?

I have an ID generator that generates unique ids during the program's execution, and currently I test if the increment returned zero.

public static class IdGenerator {
    private static int _counter = 0;
    
    public static uint GetNewId() {
        uint newId = (uint)System.Threading.Interlocked.Increment(ref _counter);
        if (newId == 0) {
             throw new System.Exception("Whoops, ran out of identifiers");
        }
        return newId;
    }
}

Given the rather large number of IDs that I generate per run, it is possibile (on an exceptionally large input) that the _counter will overflow when incremented, and I want to throw an exception in that case (crash early to ease debugging).

Excerpt from Microsoft's documentation:

This method handles an overflow condition by wrapping: if location = Int32.MaxValue, location + 1 = Int32.MinValue. No exception is thrown.


Solution

  • Just check whether newId is Int32.MinValue (before casting to uint) and throw an exception.

    The only way to get MinValue from an increment is through overflow.