为何GCC中没有__builtin_div_overflow内置函数?
GCC中整数除法溢出检测的替代方案
GCC提供了__builtin_add_overflow、__builtin_sub_overflow和__builtin_mul_overflow内置函数来检测加减乘操作的溢出,但确实没有对应的__builtin_div_overflow。对于有符号整数除法,唯一会触发溢出的场景就是**INT_MIN / -1**(同理,LONG_MIN / -1、LLONG_MIN / -1对应更长的整数类型)——补码表示下,最小负整数的绝对值比最大正整数大1,除以-1后结果超出有符号整数取值范围,属于未定义行为。
你不需要编写繁琐的条件判断,仅针对这一特定场景检测即可,以下是几种实用实现方式:
针对int类型的极简检测函数
#include <limits.h> #include <stdbool.h> inline bool div_overflow(int numerator, int denominator, int *result) { // 先处理除零错误(同样是未定义行为) if (denominator == 0) { return true; } // 唯一的除法溢出场景 if (numerator == INT_MIN && denominator == -1) { return true; } *result = numerator / denominator; return false; }
支持多整数类型的泛型宏
如果需要处理long、long long等不同类型,可以用泛型宏实现通用检测:
#include <limits.h> #include <stdbool.h> #define DIV_OVERFLOW(num, den, res) _Generic((num), \ int: _div_overflow_int, \ long: _div_overflow_long, \ long long: _div_overflow_llong)(num, den, res) static inline bool _div_overflow_int(int num, int den, int *res) { return (den == 0 || (num == INT_MIN && den == -1)) ? true : ((*res = num / den), false); } static inline bool _div_overflow_long(long num, long den, long *res) { return (den == 0 || (num == LONG_MIN && den == -1)) ? true : ((*res = num / den), false); } static inline bool _div_overflow_llong(long long num, long long den, long long *res) { return (den == 0 || (num == LLONG_MIN && den == -1)) ? true : ((*res = num / den), false); }
使用示例
int a = INT_MIN; int b = -1; int res; if (DIV_OVERFLOW(a, b, &res)) { // 处理溢出或除零错误 } else { // 使用res中的计算结果 }
需要注意,除了溢出场景,除法操作中的除零行为同样属于未定义行为,建议在检测中一并处理。
内容的提问来源于stack exchange,提问作者Vasya Pupkin
相关产品推荐
相关产品推荐

