【问题标题】:C integer overflow behaviour when assigning to larger-width integers分配给较大宽度整数时的 C 整数溢出行为
【发布时间】:2009-04-08 07:14:35
【问题描述】:

如果我在 C 中执行以下代码:

#include <stdint.h>

uint16_t a = 4000;
uint16_t b = 8000;

int32_t c = a - b;

printf("%d", c);

它会正确打印“-4000”作为结果。但是,我有点困惑:从另一个减去一个更大的无符号整数时不应该有算术溢出吗?这里有什么铸造规则?这个问题似乎有点幼稚,所以任何参考都将不胜感激。

【问题讨论】:

    标签: c casting integer overflow integer-overflow


    【解决方案1】:

    这个问题实际上有些复杂。算术表达式的操作数使用特定规则进行转换,您可以在Standard (C89) 的第 3.2.1.5 节中看到这些规则。在您的情况下,答案取决于 uint16_t 的类型。如果它小于int,比如short int,那么操作数将转换为int,你得到-4000,但在16位系统上,uint16_t可能是unsigned int并转换为有符号的type 不会自动发生。

    【讨论】:

    • 我的参考当然是旧标准。请参阅 tgamblin 对 C99 的回复。虽然他们说的一样。
    • 3.2.1.5 用于 double/float/int/etc 转换。他正在寻找该标准版本 3.2.1.1 中的积分(long/int/char/short/etc)促销。它在我上面链接的新标准的 6.3.1.1 中。
    • 他可能也想要 3.2.1.2(有符号/无符号整数)
    • 第 3.2.1.5 节也涵盖了整数转换。
    • 哦,原来如此。我想它也有长期规则等。有一个索引项将您指向 3.2.1.1 进行积分促销。
    【解决方案2】:

    简短的回答是这些在减法期间都被提升为int。对于长答案,请查看C standard 的第 6.3.1.1 节,其中讨论了算术表达式中的 整数提升。标准中的相关语言:

    如果 int 可以表示 原始类型,值为 转换为 int;否则,它是 转换为 unsigned int。这些 被称为整数促销。 所有其他类型均由 整数促销。

    细节也在那里,但它们变得非常糟糕。

    【讨论】:

      【解决方案3】:

      在减法过程中,两个操作数都被提升为int32_t。如果结果大于int32_t 的最大值,您会看到溢出。

      【讨论】:

        【解决方案4】:

        实际上存在溢出,但 C 没有告诉你。

        溢出的值在解释为有符号整数时恰好为 -4000。这在 2 的补码机器上按设计工作。

        尝试将结果解释为无符号,当 u1

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-10-22
          • 1970-01-01
          • 1970-01-01
          • 2012-01-19
          • 1970-01-01
          相关资源
          最近更新 更多