Integer Overflow Detection

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

Source 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.

+7
source share
2 answers

You can easily check it with the built-in 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 cannot put this in a function because calling a function can reset the flag. You will want to install it immediately after the operation that interests you.

You can create a type that uses operator overloading to overflow: http://arsdnet.net/dcode/ranged.d is one example. Or I think the module is std.bigint in the standard library, which avoids overflow by offering an arbitrarily large integer type.

+5
source

First, the code you gave doesn't even compile, because all the whole math with sizes smaller than int is executed using int . So the result of a + b is int , and int will not implicitly convert to ubyte , because this is a narrowing of the conversion. If you want to assign it to c , you will need to distinguish it.

 ubyte c = cast(ubyte)(a + b); 

Now this is clearly an uncontrolled transformation, and it will happily insert 44 into c (since the result of the cast sets the values ​​to 100 and 200 ). If you want a test conversion, use std.conv.to :

 ubyte c = to!ubyte(a + b); 

This will raise a ConvOverflowException (which is a subclass of ConvException ) because the result will not match the requested type.

If you want to make a throw yourself and then check if there was an overflow, then you are essentially the same boat as C / C ++, and there are no carry flags or anything like that. Perhaps such a thing exists if you check the assembly code. I dont know. But language, of course, does not give anything like that. std.conv.to shows this by checking the result and seeing if it is too small (depending on the sign and type of argument).

+8
source

All Articles