C++ 类型中的通用溢出检测
Generic overflow detection in C++ types
我想要一个可以检测所有类型溢出的通用方法,例如 char、unsigned char、short、unsigned short、int32、unsigned int32、long、unsigned long、int64、unsigned int64 等
在后来的 C++ 中,我们可以使用 __builtin_add_overflow_p
来检测加法溢出。宏可以这样
#define ADD_OVERFLOW(a, b) __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)
问题是这不会检测 8 位或 16 位类型(例如 char 或 short)的溢出。需要一种通用且有效的机制来检测溢出。高效意味着尽可能减少 cpu 周期,因为检查需要放在很多地方。低效的检查会减慢程序的速度。因此效率是必须的
我也试过了
#define ADD_OVERFLOW(a, b) ((__typeof__(a))(a + b) < a)
它不适用于某些有符号类型,例如 int32
是否有适用于 C++ 中所有类型的通用解决方案?
__builtin_add_overflow_p
是否适用于 8 位和 16 位类型。问题是 (__typeof__ ((a) + (b)))
是 int
,它不会在 int
.
中溢出
您可能想要的是 a
和 b
是同一类型,并检查该类型的加法是否溢出:
template<typename T>
constexpr bool add_overflow(T a, T b) {
return __builtin_add_overflow_p(a, b, T{0});
}
static_assert(add_overflow((signed char) 125, (signed char) 100));
static_assert(!add_overflow((signed char) 125, (signed char) -3));
// Or if you *must* use a macro:
#define ADD_OVERFLOW(a, b) __builtin_add_overflow_p(a, b, \
std::enable_if_t< \
std::is_same_v<std::decay_t<decltype(a)>, std::decay_t<decltype(b)>>, \
std::decay_t<decltype(a)>>{0})
我想要一个可以检测所有类型溢出的通用方法,例如 char、unsigned char、short、unsigned short、int32、unsigned int32、long、unsigned long、int64、unsigned int64 等
在后来的 C++ 中,我们可以使用 __builtin_add_overflow_p
来检测加法溢出。宏可以这样
#define ADD_OVERFLOW(a, b) __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)
问题是这不会检测 8 位或 16 位类型(例如 char 或 short)的溢出。需要一种通用且有效的机制来检测溢出。高效意味着尽可能减少 cpu 周期,因为检查需要放在很多地方。低效的检查会减慢程序的速度。因此效率是必须的
我也试过了
#define ADD_OVERFLOW(a, b) ((__typeof__(a))(a + b) < a)
它不适用于某些有符号类型,例如 int32 是否有适用于 C++ 中所有类型的通用解决方案?
__builtin_add_overflow_p
是否适用于 8 位和 16 位类型。问题是 (__typeof__ ((a) + (b)))
是 int
,它不会在 int
.
您可能想要的是 a
和 b
是同一类型,并检查该类型的加法是否溢出:
template<typename T>
constexpr bool add_overflow(T a, T b) {
return __builtin_add_overflow_p(a, b, T{0});
}
static_assert(add_overflow((signed char) 125, (signed char) 100));
static_assert(!add_overflow((signed char) 125, (signed char) -3));
// Or if you *must* use a macro:
#define ADD_OVERFLOW(a, b) __builtin_add_overflow_p(a, b, \
std::enable_if_t< \
std::is_same_v<std::decay_t<decltype(a)>, std::decay_t<decltype(b)>>, \
std::decay_t<decltype(a)>>{0})