【问题标题】:Generic overflow detection in C++ typesC++ 类型中的通用溢出检测
【发布时间】:2021-12-30 13:04:47
【问题描述】:

我想要一个通用方法,可以检测所有类型的溢出,例如 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++ 中所有类型的通用解决方案?

【问题讨论】:

  • 你说“[o]n 以后的 C++ 我们可以使用__builtin_add_overflow_p 来检测溢出”。这是不正确的。标准 C++ 中没有 __builtin_add_overflow_p 函数。它是特定编译器的扩展。
  • 转换为足够大的类型以容纳任何结果(对于小于int 的类型,使用int)。做算术运算。测试原始类型溢出的结果。分析应用程序以查看其效率。我会编写一个模板类来完成以上所有工作。
  • 在(签名)添加之后测试溢出已经太晚了,因为 UB。

标签: c++ types overflow gnu


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2023-03-22
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多