PIC 中的整数溢出——流到哪里去了?

发布于 2024-12-25 12:39:26 字数 560 浏览 1 评论 0原文

使用 Microchip 18f4620 PIC。不过,这应该是一个标准的 ANSI C 问题。

假设我有

unsigned int16 badFlow=65535 //max unsigned int16 value

This 的二进制值为 1111 1111 1111 1111

如果我那么

badFlow++;

位模式变为 1 0000 0000 0000 0000 17 位。显然 badFlow == 0,但是额外的翻转位要么

  1. 被丢弃
  2. ,要么驻留在 byte* flowPtr = &badFlow+2; 的任何位置 点。

我假设是后者,但希望是前者。

我的问题:一位同事编写了一些错误的代码,其计数器在所有生产的产品上溢出了大约 2 年。考虑到我们的客户使用这些工具的费用,由于潜在的不良数据,这将带来数百万美元的危险。

Working with a Microchip 18f4620 PIC. This should be a standard ANSI C question, though.

Say I have

unsigned int16 badFlow=65535 //max unsigned int16 value

This has a binary value of 1111 1111 1111 1111.

if I then

badFlow++;

the bit pattern becomes 1 0000 0000 0000 0000
17 bits. Obviously badFlow == 0, but the additional flipped bit either

  1. gets discarded
  2. or resides at wherever byte* flowPtr = &badFlow+2;
    points.

I'm assuming the latter, but hoping for the former.

My problem: a coworker has written some bad code with a counter that has been overflowing on all produced products for ~2 years. Considering what our customers charge for use of these tools, that's a few million dollars in peril due to potentially bad data.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

烟若柳尘 2025-01-01 12:39:26

C 中的算术使用进行,而不是内存中的字节。您的表达式 badFlow++ 相当于 badFlow = badFlow + 1。右侧被评估为类型 int (由于默认提升,假设 int 大于 16 位;如果 int 仅是 16位,那么它将被评估为 unsigned int),结果为 65536,然后当 65536 被分配给无符号 16 位变量时,它会以 65536 为模进行减少,从而得到0.

从这个答案中得到的重要一点是,badFlow++ 不是对 &badFlow 处内存的直接操作(尽管它可能实现)在某些实现上也是如此)。它只是加法和赋值的简写。

Arithmetic in C takes place with values, not bytes in memory. Your expression badFlow++ is equivalent to badFlow = badFlow + 1. The right-hand side is evaluated as type int (due to default promotions, assuming int is larger than 16 bits; if int is only 16 bits then it would be evaluated as unsigned int) resulting in 65536, then when 65536 is assigned into an unsigned 16-bit variable, it is reduced modulo 65536, resulting in 0.

The important thing to get out of this answer is that badFlow++ is not a direct operation on the memory at &badFlow (although it could possibly be implemented as such on some implementations). It's simply shorthand for an addition and assignment.

把昨日还给我 2025-01-01 12:39:26

最高有效数字被丢弃。许多处理器都有一个状态寄存器,指示发生了溢出,但从 C 中看不到(您必须在汇编中工作才能使用它)

The most significant digit gets discarded. Many processors will have a status register that indicates that an overflow occurred, but that is not visible from C (you'd have to work in assembly to use it)

新雨望断虹 2025-01-01 12:39:26

不会溢出到badFlow之后的内存中。

It will not overflow into memory that follows badFlow.

夏至、离别 2025-01-01 12:39:26

选项1是正确的,溢出被默默丢弃。

Option 1 is correct, the overflow is silently discarded.

赠佳期 2025-01-01 12:39:26

标准 C 中整数类型的上溢或下溢通常是一种安全操作,并且不会修改超出所访问变量范围的内存。在标准 C 中,溢出位被丢弃,但实现可能会将其存储在特殊的溢出寄存器或专用内存位置中。例如,在 i386 系统上,溢出在“进位标志”中发出信号。

编辑:正如 @aix 指出的那样,进位标志并不是由每个相关的 i386 汇编指令更新的。这当然是一个实现细节; C 语言并没有对进位标志给予任何关注。

编辑2:正如 R. 指出的那样,签名溢出是未定义的行为,尽管我见过的每个实现仍然安全地对待它。

Overflowing or underflowing an integer type in standard C is generally a safe operation and will not modify memory beyond the bounds of the variable being accessed. In standard C, the overflow bit is discarded, though the implementation may store it in a special overflow register or dedicated memory location. For instance, on i386 systems, overflow is signalled in the "carry flag."

Edit: As @aix points out, the carry flag isn't updated by every relevant i386 assembly instruction. This is an implementation detail of course; the C language doesn't give two hoots about carry flags.

Edit 2: And as R. points out, signed overflow is undefined behaviour, though every implementation I've seen still treats it safely.

过潦 2025-01-01 12:39:26

迁移到 uint32 并发布新的软件版本将是正确的方法。

Moving to uint32 and making a new software release would be the right way to go..

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文