在寻找对有符号和无符号整数算术进行溢出检查的函数时,我遇到了这个答案,它提供了很好的编译器内在特性,可以在GCC中执行检查数学。由于我目前正在编写的代码需要是跨平台的,所以我需要MSVC (Microsoft Visual Studio)编译器也需要类似的东西。
是否存在或者我必须手动实现它?
对于无符号加减法,MSVC有_addcarry_u16/32/64
和_subborrow_u16/32/64
,它们都定义在add
和sub
,而不是adc
和sbb
,如果你为进位传递常数0。
遗憾的是,没有类似的函数返回溢出标志。
对于64×64乘法,__mulh
和__umulh
返回结果的高64位,可以将其与无符号情况下的0或有符号情况下的low >> 63
进行比较。也有_[u]mul128
函数返回整个结果,但我认为它们使用起来会更麻烦,并且会在优化上生成相同的代码(我还没有测试过)。
除法有_[u]div64
和_[u]div128
,定义在<immintrin.h>
中。它们在溢出的情况下做什么似乎没有文档记录,但它们很可能引发#DE,这可能被SEH捕获。
在其他情况下,可能没有什么比以更高的精度计算结果然后进行边界检查更好的了。