发生溢出,但errno不是ERANGE.这是怎么发生的?

lim*_*imp 5 c overflow errno

我正在尝试使用errno来检测我是否执行了导致溢出的操作.然而,虽然我写了一个故意溢出的功能,但是errno == ERANGE是假的.这里发生了什么?

这是代码:

#include <stdio.h>
#include <errno.h>

int main(int argc, char* argv[]) {
    unsigned char c = 0;
    int i;

    for (i = 0; i< 300; i++) {
        errno = 0;
        c = c + 1;
        if (errno == ERANGE) {// we have a range error
            printf("Overflow. c = %u\n", c);
        } else {
            printf("No error. c = %u\n", c);
        }
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我预计这会在我们添加1到255的位置发出溢出错误,但没有错误.这是(截断的)输出:

No error. c = 245
No error. c = 246
No error. c = 247
No error. c = 248
No error. c = 249
No error. c = 250
No error. c = 251
No error. c = 252
No error. c = 253
No error. c = 254
No error. c = 255
No error. c = 0
No error. c = 1
No error. c = 2
No error. c = 3
No error. c = 4
No error. c = 5
No error. c = 6
No error. c = 7
No error. c = 8
No error. c = 9
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么它没有检测到错误,以及我如何更改它或以其他方式创建一个可以检测我的值是否溢出的函数?注意:最终我想用long ints 做这个,所以不可能简单地将它转换为更大的数据类型.

编辑:

我已经发现了一些简单的函数来分别检测积分数据类型的加法和乘法的溢出.它并未涵盖所有情况,但它涵盖了很多情况.

乘法:

int multOK(long x, long y)
/* Returns 1 if x and y can multiply without overflow, 0 otherwise */
{
    long p = x*y;

    return !x || p/x == y;
}
Run Code Online (Sandbox Code Playgroud)

签名补充:

int addOK(long x, long y)
/* Returns 1 if x and y can add without overflow, 0 otherwise */
{
    long sum = x+y;
    int neg_over = (x < 0) && (y < 0) && (sum >= 0);
    int pos_over = (x >= 0) && (y >= 0) && (sum < 0);
    return !neg_over && !pos_over;
}
Run Code Online (Sandbox Code Playgroud)

无符号加法:

int unsignedAddOK(unsigned long x, unsigned long y)
/* Returns 1 if x and y can add without overflow, 0 otherwise */
{
    unsigned long sum = x+y;

    return sum > x && sum > y;
}
Run Code Online (Sandbox Code Playgroud)

tom*_*ahh 2

Errno不是处理器设置的变量,它仅被系统调用和一些标准函数用来报告错误。

除了在每次循环迭代中验证是否之外,我不知道有任何技术可以检测您的要求c < c + 1

编辑:经过一些研究,我发现了这个关于状态寄存器的维基百科,状态寄存器是指示此类错误的CPU标志。