编译器是否有可能检测整数溢出或其他数据类型溢出的可能性

Is it possible for compilers to detect the possibility of an integer overflow or other data type overflow?

本文关键字:溢出 其他 数据类型 可能性 编译器 有可能 检测 整数 是否      更新时间:2023-10-16

是否可以在编译时检测或防止整数溢出?

如果未检测到溢流,并且发生在Run-Tine处,是否可以检测到?我在某个地方读到,处理器将具有特定标志,以防一个操作处有溢出。

如何读取处理器的特定标志?我应该问这个问题吗?

编辑:

我的问题是关于签名和未签名的溢出。当我们有一个无符号变量时,它仍然可以溢出并将自己设置为0或接近0的东西,对吗?还是我缺少的东西?

在一般情况下,无法在编译时检测和防止溢出。在特定情况下,可以在编译时检测到明显的溢出,例如在恒定表达评估过程中发生的溢出,并且编译器通常会报告此类问题。

请注意,溢出是C.未签名的算术中签名算术的问题。

编译器所做的是假设,该签名算法由程序员编码执行的算法不会 溢出并基于此假设优化代码。例如,积极的优化器可以省略以下测试:

int test(int x) {
    if (x + 1 > x) {
        /* this is not a way to test for potential wrap-around
         * since overflow is UB, the compiler can assume that incrementing
         * an int always evaluates to a larger int.
         */
        return x + 1;
    }
    return 0;
}

在C标准中未指定在运行时检测溢出。代码生成器可以以相对较低的开销添加指令,以执行特定的溢出处理。其他语言这样做,但是许多C开发人员不愿意拥有最小的开销,因为他们错误地认为从未发生过。将其作为调试模式很有用,现代的海湾合作委员会和clang编译器为地址检查和其他问题提供了 Sanitize 选项。例如,您应该检查-fsanitize=undefined

  • clang 6文档不确定的行为消毒剂

对于未签名的溢出,可以通过检查处理器标志的额外生成的代码来检测运行时检测,但是由于定义了行为,因此SaniTization选项似乎不在乎这种类型的 Overflow 。/p>

另一种方法可能更适合您的目的:GCC提供内置功能,以执行签名和未签名的算术并在运行时报告溢出:

  • https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/integer-overflow-builtins.html

仅回答问题的第二部分:

一些编译器具有特殊的内置来检测溢出。通常,它增加了一个庞大的开销,并且您的整数计算要比执行相同检查的C代码要快得多,但要快得多。https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/integer-overflow-builtins.html

相关文章: