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.

中溢出

您可能想要的是 ab 是同一类型,并检查该类型的加法是否溢出:

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})