【问题标题】:C: confirmation of simple arithmetic outputC:简单算术输出的确认
【发布时间】:2011-12-19 06:13:28
【问题描述】:

我能否确认以下 C 代码为 b 提供了未定义的结果:

unsigned a = 0;
int b = a - 1;

【问题讨论】:

  • 我看到的结果总是-1:ideone.com/cjArRcodepad.org/xoAD6LIJ
  • @hari:原因是这样的:a 是无符号的,而-1 是整数,所以-1 被提升为无符号。所以我们有b = a + UINT_MAX。但是如果UINT_MAX > INT_MAX,那么这个结果不适合b的可表示范围,因此给出未定义的结果
  • @hari:C 以明确定义的方式将 int 转换为无符号:如果 int 为非负数,则无符号结果具有相同的值。如果 int 为负数,则无符号结果等于添加到 UINT_MAX + 1 的 int 值。但我发现预期的结果违反直觉,所以我在这个论坛上仔细检查以确保。
  • a-b 和 a+(-b) 不等效。当b 是INT_MIN 并且a 是负数时,前者对于有符号整数是明确定义的。后者不是。
  • 不是实现定义的。不明确的。根据 6.5 表达式:“如果在计算表达式期间出现异常情况(即,如果结果未在数学上定义或不在其类型的可表示值范围内),则行为未定义。”

标签: c math int undefined unsigned


【解决方案1】:

当您将 unsigned 分配给 int 时,会发生隐式类型转换。所以,它不是未定义的行为。

【讨论】:

    【解决方案2】:

    (§6.3.1.3/3):“......结果是实现定义的,或者引发了实现定义的信号。”

    在典型的二进制补码硬件上,我希望结果为 -1。

    请注意,结果是实现定义的,而不是未定义的。

    【讨论】:

    • 我能澄清一下实现定义和未定义的区别吗?
    • @tyty:实现定义意味着您的特定实现必须选择一些一致的规则,并记录该规则是什么。另一方面,如果它未定义,则它不需要保持一致或记录在案。
    • @tyty:实现定义本质上意味着,根据编译器的实现,标准为编译器的奇思妙想留下了一些功能。但是你可以相信特定的编译器会给你调用该行为的场景的结果相同。未定义意味着任何事情都可能发生,在这种情况下,标准不要求编译器执行任何特定操作,程序可能会崩溃或不崩溃,或者龙可能会飞。对于以下场景,您不能期望相同的行为即使对于相同的编译器,也会调用相同的行为。
    【解决方案3】:

    它总是给出值

     a=0,b=-1  
    

    仅当您想在线查看时c compiler

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-24
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 2021-12-26
      • 1970-01-01
      • 2016-02-18
      相关资源
      最近更新 更多