Here's how you can do it:
uint32 addui(uint32 position, int32 offset, int* overflow) { *overflow = (((offset >= 0) && (0xFFFFFFFFu - position < (uint32)offset)) || ((offset < 0) && (position < (uint32)-offset))); return position + offset; }
The suffix u must ensure that the constant 0xFFFFFFFF is of unsigned type (hexadecimal constants without suffixes can be signed or unsigned, depending on the value and how your compiler defines int, long and long) and, therefore, the expression on the left is <unsigned. It may not be necessary, but I'm a little tired to understand, right. This will not hurt for sure.
Tasks (uint32) should shut up the compiler, which might think that we are doing something stupid (comparing signed with unsigned).
UPDATE If int32 has a representation with two additions and offset = -0x80000000, the -offset expression -offset allowed to raise an implementation-defined signal or, possibly, even cause undefined behavior in C (see sections 6.3.1.3 Signed and unsigned integers and 7.20.6.1 The abs, labs and llabs functions for C99), but practically never happens, because on most platforms negation is implemented as a simple instruction (or several) that does not cause any exception / interrupt / trap / event in the CPU and has little value for generating additional code to verify this case with the edge moreover, integers are represented in 2 complement codes, and the absolute value of -0x80000000 is 0x80000000, which can be convenient (for example, for calculating absolute values). The CPU does not really care about signed integers and even uses the same instructions to add and subtract for both (this is the advantage of the 2nd addition), and it rarely cares about integer overflows, as they occur in software and are a way of life. Keep this in mind, but do not sweat.
See how they are implemented in Microsoft SafeInt for C ++ ( Code , Introduction , In MSDN , Video ) and IntSafe for C ( Intro + Code , In MSDN ).
Alexey Frunze
source share