【问题标题】:Is this a VC compiler bug? About unsigned integer wrapping这是 VC 编译器的错误吗?关于无符号整数换行
【发布时间】:2013-11-10 17:01:37
【问题描述】:

我认为下面的C程序应该输出1

#include <stdio.h>
int main()
{
    unsigned int n=18u;
    while ((n+17u)>=17u) n-=17u;
    printf("%u\n",n+17u);
    return 0;
}

但在VC6、Visual Studio 2010或Visual Studio 2012中编译,均处于发布模式,程序不输出任何内容,也不退出。

这是VS2012生成的汇编代码:

00BD1000  mov         eax,12h
00BD1005  lea         eax,[eax-11h]
00BD1008  jmp         main+5h (0BD1005h)

看来编译器做了一些优化,生成了一个无限循环。

我认为((n+17u)&gt;=17u) 并不总是正确的,因为如果n==0xFFFF..FFn+17u 会换成16u

是我错了,还是编译器错了?

【问题讨论】:

  • 这可能是未定义的行为。 (我对 C 的了解不够好,无法确定)
  • 我在VS2012中看到了。已在 VS2013 中修复。
  • @HansPassant 有任何链接可以确认吗?太吓人了。
  • 在 VS2012 更新 4 中仍未修复。

标签: c visual-c++ unsigned


【解决方案1】:

gccclang 都编译掉该循环,将其替换为常量 1 的 printf(使用 -O3。)

我认为你观察到的 VC 行为是一个错误:无符号算术是明确定义的,你是对的,溢出应该环绕到小于 17 的整数。所以gccclang 做对了.

【讨论】:

    【解决方案2】:

    MacOS 上的 gcc 和 clang:

    #include <stdio.h>
    int main()
    {
        unsigned int n=18u;
        while ((n+17u)>=17u) {
            n-= 17u;
            printf("n=%u %u >= %u\n", n, n+17u, 17u);
        }
        printf("%u\n",n+17u);
        return 0;
    }
    

    打印

    n=1 18 >= 17
    n=4294967280 1 >= 17
    1
    

    所以 n 变“大”并且 n 的增量使其再次“变小”并且循环结束。 我说的不太好。

    编译器错误很少见,但我认为您找到了。恭喜。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-05-29
      相关资源
      最近更新 更多