2

While looking for functions that do overflow checks on signed and unsigned integer arithmetics, I came across this answer, which presents nice compiler intrinsics to do checked math in GCC. Since the code I'm currently writing needs to be cross-platform, I need something similar for the MSVC (Microsoft Visual Studio) compiler as well.

Does that exist or do I have to implement it manually?

PMF
  • 14,535
  • 3
  • 23
  • 49

1 Answers1

3

For unsigned addition and subtraction, MSVC has _addcarry_u16/32/64 and _subborrow_u16/32/64, all defined in <intrin.h>. They seem to produce optimal code, including generating add and sub instead of adc and sbb if you pass constant 0 for the carry in.

Unfortunately, there are no analogous intrinsics that return the overflow flag.

For 64×64 multiplication, __mulh and __umulh return the high 64 bits of the result, which you can compare with 0 in the unsigned case or low >> 63 in the signed case. There are also _[u]mul128 functions that return the whole result, but I think they would be more cumbersome to use and would generate the same code with optimization on (I haven't tested that).

For division, there are _[u]div64 and _[u]div128, defined in <immintrin.h>. It seems to be undocumented what they do in the case of overflow, but they most likely raise #DE, which could be caught with SEH.

In other cases, there's probably nothing better than to calculate the result at a higher precision and then bounds-check it.

benrg
  • 1,395
  • 11
  • 13
  • Looks like that's pretty much it. `_addcarry_u32` returns the carry flag, which is exactly what is required. I'll test these today. – PMF Oct 14 '21 at 08:53
  • `intsafe.h`, mentioned by Hans above seems to be a bit more complete, but both are doing the job, thanks. – PMF Oct 16 '21 at 17:21