Search code examples
intd

Detecting integer overflow


How to detect integer overflow in D? (check carry flag?)

Original example:

ubyte a = 100;
ubyte b = 200;
ubyte c = a + b;
// c can't represent 300; how to detect the overflow now?

Revised example:

uint a = 2_000_000_000;
uint b = 3_000_000_000;
uint c = a + b;
// c can't represent 5_000_000_000; how to detect the overflow now?

Also with multiplication and pre/post-increment.


Solution

  • Update in 2021: this technique only works if you use dmd without optimizations (and even then probably better to do other approaches). To work in more cases, you can do all the operations in inline assembly (which btw is likely to break optimizers), or use the core.checkedint operations which have a ref bool overflowed argument you can check at the end of the operation (which is also inline-friendly btw for the optimizer again).

    Original post follows:

    You can check it pretty easily with some inline assembly:

    asm { jo overflowed; } // for checking signed types
    // or
    asm { jc overflowed; } // use this for checking unsigned types
    
    /* continue going */
    
    return;
    
    overflowed:
    
    /* do whatever to handle it */
    

    Note: you probably can't put this in a function because calling the function can reset the flag. You'll want to put it inline right after the operation you're interested in.

    It is possible to make a type that uses operator overloading to throw on overflow: http://arsdnet.net/dcode/ranged.d is one example. Or I think the module is std.bigint in the standard library that avoids overflow by offering an arbitrarily large integer type.