【转载】gcc.gnu.org:内置函数执行溢出检查算法

转载:https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html

下面的内置函数可以执行简单的算术运算,并检查运算是否溢出。

内置函数:bool __builtin_add_overflow( type1 a, type2 b, type3 * res)
内置函数:bool __builtin_sadd_overflow(int a,int b,int * res)
内置函数:bool __builtin_saddl_overflow(长整数a,长整数b,长整数* res)
内置函数:bool __builtin_saddll_overflow(long long int a,long long int b,long long int * res)
内置函数:bool __builtin_uadd_overflow(无符号整数a,无符号整数b,无符号整数* res)
内置函数:bool __builtin_uaddl_overflow(无符号长整数a,无符号长整数b,无符号长整数* res)
内置函数:bool __builtin_uaddll_overflow(unsigned long long int a,unsigned long long int b,unsigned long long int * res)

这些内置函数将前两个操作数提升为无限精度带符号类型,并对这些提升的操作数执行加法运算。然后将结果强制转换为第三个指针参数指向的类型并存储在那里。如果存储的结果等于无限精度的结果,则内置函数返回 false ,否则返回 true 。由于加法运算以无穷大的符号精度执行,因此这些内置函数对所有参数值具有完全定义的行为。

第一个内置函数允许操作数的任意积分类型,结果类型必须是指向枚举型或布尔型以外的某个积分类型的指针,其余的内置函数都有明确的整数类型。

编译器会尽量使用硬件指令来实现这些内置函数,比如加法后溢出时的条件跳转,携带时的条件跳转等。

内置函数:bool __builtin_sub_overflow( type1 a, type2 b, type3 * res)
内置函数:bool __builtin_ssub_overflow(int a,int b,int * res)
内置函数:bool __builtin_ssubl_overflow(长整数a,长整数b,长整数* res)
内置函数:bool __builtin_ssubll_overflow(long long int a,long long int b,long long int * res)
内置函数:bool __builtin_usub_overflow(无符号整数a,无符号整数b,无符号整数* res)
内置函数:bool __builtin_usubl_overflow(无符号长整数a,无符号长整数b,无符号长整数* res)
内置函数:bool __builtin_usubll_overflow(无符号长整型a,无符号长整型b,无符号长整型* res)

这些内置函数与上面的加法溢出检查内置函数类似,只是它们执行的是减法,从第一个参数中减去第二个参数,而不是加法。

内置函数:bool __builtin_mul_overflow( type1 a, type2 b, type3 * res)
内置函数:bool __builtin_smul_overflow(int a,int b,int * res)
内置函数:bool __builtin_smull_overflow(长整数a,长整数b,长整数* res)
内置函数:bool __builtin_smulll_overflow(long long int a,long long int b,long long int * res)
内置函数:bool __builtin_umul_overflow(无符号整数a,无符号整数b,无符号整数* res)
内置函数:bool __builtin_umull_overflow(无符号长整数a,无符号长整数b,无符号长整数* res)
内置函数:bool __builtin_umulll_overflow(unsigned long long int a,unsigned long long int b,unsigned long long int * res)

这些内置函数与上面的加法溢出检查内置函数类似,只是它们执行的是乘法,而不是加法。

下列内置函数可以检查简单的算术运算是否会溢出。

内置函数:bool __builtin_add_overflow_p( type1 a, type2 b, type3 c)
内置函数:bool __builtin_sub_overflow_p( type1 a, type2 b, type3 c)
内置函数:bool __builtin_mul_overflow_p( type1 a, type2 b, type3 c)

这些内置函数类似于 __builtin_add_overflow , __builtin_sub_overflow 或 __builtin_mul_overflow ,不同之处在于它们不将算术运算的结果存储在任何地方,并且最后一个参数不是指针,而是某些具有枚举或布尔类型以外的整数类型的表达式。

内置函数将前两个操作数提升为无限精度带符号类型,并对这些提升的操作数执行加法运算。然后将结果转换为第三个参数的类型。如果强制转换结果等于无限精度结果,则内置函数返回 false ,否则返回 true 。将忽略第三个参数的值,仅评估第三个参数中的副作用,并且不对最后一个参数执行积分参数提升。如果第三个参数是位字段,则用于结果强制转换的类型具有给定位字段的精度和正负号,而不是基础类型的精度和正负号。

例如,可以使用下面的宏在编译时可移植地检查两个常数整数相加是否会溢出,只有在已知安全的情况下才执行加法,并且不会触发一个-Woverflowwarning.

#define INT_ADD_OVERFLOW_P(a, b) \
   __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)

enum {
    
    
    A = INT_MAX, B = 3,
    C = INT_ADD_OVERFLOW_P (A, B) ? 0 : A + B,
    D = __builtin_add_overflow_p (1, SCHAR_MAX, (signed char) 0)
};

编译器会尽量使用硬件指令来实现这些内置函数,比如加法后溢出时的条件跳转,携带时的条件跳转等。

猜你喜欢

转载自blog.csdn.net/weixin_43919932/article/details/123666702
今日推荐