【问题标题】:integer overflow in a PIC -- where's the flow go?PIC 中的整数溢出——流向何方?
【发布时间】:2023-03-16 14:00:02
【问题描述】:

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

说我有

unsigned int16 badFlow=65535 //max unsigned int16 value

它的二进制值为1111 1111 1111 1111

如果我那么

badFlow++;

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

  1. 被丢弃
  2. 或居住在byte* flowPtr = &badFlow+2;的任何地方 分。

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

我的问题:一位同事使用计数器编写了一些错误代码,该计数器已在所有生产的产品上溢出约 2 年。考虑到我们的客户对使用这些工具的收费,由于潜在的不良数据,这意味着几百万美元的风险。

【问题讨论】:

  • 听起来你应该使用更大的数据类型。
  • @Mysticial 是的。这已经得到纠正。我只是想弄清楚我们是否需要回去纠正过去的不当行为。
  • 我认为 #2 无效 - resides at wherever byte* flowPtr = &badFlow+2;
  • 这可能很晚了,但我很好奇;你的编译器是什么?

标签: c int pic integer-overflow


【解决方案1】:

C 中的算术运算使用,而不是内存中的字节。您的表达式badFlow++ 等价于badFlow = badFlow + 1。右侧被评估为int 类型(由于默认促销,假设int 大于16 位;如果int 只有16 位,那么它将被评估为unsigned int)导致65536,那么当 65536 赋值给一个无符号的 16 位变量时,它会以 65536 为模减少,得到 0。

摆脱这个答案的重要一点是badFlow++ 不是对&badFlow 内存的直接操作(尽管它可能在某些实现中这样实现)。它只是加法和赋值的简写。

【讨论】:

  • 谢谢。这真的很有启发性
【解决方案2】:

最重要的数字被丢弃。许多处理器都会有一个状态寄存器来指示发生了溢出,但这在 C 中是不可见的(您必须在汇编中工作才能使用它)

【讨论】:

  • 这在 C 中是可见的。例如,XC8 编译器将允许您读取状态寄存器。我认为所有的编译器都会允许这样做。
  • 它不是标准 C 的一部分。一些编译器确实提供了访问它的方法(通常是汇编宏),但它取决于系统。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      编辑:正如@a​​ix 指出的那样,进位标志不会被每个相关的 i386 汇编指令更新。这当然是一个实现细节; C 语言不会对进位标志大加指责。

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

      【讨论】:

      • 请注意,i386 注释仅部分准确:INC(增量)指令更改进位标志。
      • -1 这个答案是完全错误的,除非你用 unsigned 来限定它。有符号整数溢出是危险的 UB。
      • 很公平。正在更新答案。
      • 您的更新更糟,因为它表明您知道 UB 但并不在意,而且它错误。在 5-10 年前,有符号溢出在 gcc 或其他现代编译器上的行为不像模运算。
      • 我没有提到模运算。我刚刚说过,我知道没有编译器在出现带符号溢出时会变得危险(即崩溃、写入错误的内存等)。而且由于最初的问题是关于无符号溢出,因此在回答时区分并不重要。
      【解决方案6】:

      移动到uint32 并发布新的软件版本将是正确的方式..

      【讨论】:

      • 是的。绝对是这里的计划。推出新版本(涉及旅行和大量机械工作)是一个很大的失败,但我们会这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 2014-01-24
      • 2014-06-08
      相关资源
      最近更新 更多