整数溢出测试运算符? (安培; +)

时间:2017-09-17 21:17:11

标签: c integer integer-overflow

这个问题可能只是another case错误地解释了操作符。但不久之前,我看到有人发推文关于运营商的信息,据说可以用来检查C中的整数溢出。即&+(&符号加)运算符,它可以像以下一样使用:

#include <stdio.h>
#include <stdint.h>

int main()
{
    uint32_t x, y;

    x = 0xFFFFFFFF;
    y = 1;

    if (x &+ y) {
        printf("Integer overflow!\n");
    } else {
        printf("No overflow\n");
    }

    return 0;
}

它似乎按照人们的预期工作,GCC 6在使用这些参数进行编译时不会给我任何警告或错误:gcc -Wall -Wextra -Werror of.c

但奇怪的是,我还没有找到关于此运算符的任何文档,而且我从未在任何地方看到过它。有人可以解释一下这是如何工作的吗?

3 个答案:

答案 0 :(得分:8)

表达式

x &+ y

被解析为

x & (+y)

使用一元加运算符,它没有效果(在这种情况下)并且只返回y。这意味着表达式等同于

x & y

测试整数溢出,而只检查x和y是否有任何共同位。尝试将x和y更改为1,看看会发生什么;即使没有发生溢出,它也会报告溢出。

答案 1 :(得分:3)

这可能是一个笑话,没有&+运算符这样的东西。如果你写x&+y,它被解释为x & (+y),其中&是二进制按位和运算符,而+是一元加运算符,除了可能执行算术之外什么都不做促销(例如,如果yshortchar,则会将其提升为int;在您的情况下,它不会执行任何操作。

无论如何,这个表达式与检查溢出并没有真正的严格关系。

答案 2 :(得分:1)

您可能希望使用__builtin_add_overflow(完全通用,有些不太常见)或__builtin_uadd_overflow(对于unsigned int s)

#include <stdio.h>
#include <stdint.h>

int main()
{
    uint32_t x, y;

    x = 0xFFFFFFFF;
    y = 1;

    if (__builtin_add_overflow(x, y, &x)) {
        printf("Integer overflow!\n");
    } else {
        printf("No overflow\n");
    }

    return 0;
}

gcc / clang,AFAIK中没有内置检查操作符,而&+只有&后跟一元+

我亲自使用包含这些内置的包装宏,如果它们可用,或者回归到一个内置的解决方案,其灵感来自溢出检查代码,可以在 https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow