整数溢出测试运算符? (&+)

Integer overflow test operator? (&+)

这个问题可能只是 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

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

表达式

x &+ y

被解析为

x & (+y)

使用一元加运算符,它没有任何效果(在本例中),只是 returns y。这意味着表达式等同于

x & y

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

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

总之,这个表达式与检查溢出没有严格的关系。

您可能想使用 __builtin_add_overflow (fully generic, and somewhat less common) or __builtin_uadd_overflowunsigned ints)

#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 中没有内置检查运算符,&+ 只是 & 后跟一元 +

我个人正在使用使用这些内置函数的包装宏(如果它们可用),或者回退到受溢出检查代码启发的无内置解决方案 https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow