Visual Studio C 程序 运行 使用 VS 编译器失败但使用 Clang

Visual Studio C program run fails with VS compiler but works with Clang

配置:Win10 64 位,安装了所有更新和 Clang v12.0 的 VS2019,并在 null 语句上设置了断点。

如果使用 VS 编译器编译,下面的第一个版本的代码会在 Foo 第一次输出到控制台后命中断点,但如果使用 Clang 编译,则会按预期循环。第二个版本按预期使用 VS 编译器和 Clang 循环。如果我删除断点,两个版本都会按预期使用两个编译器循环。为什么断点会导致第一个版本与 VS 编译器一起失败?

版本 1:

#include <stdio.h>
int main(void)
{
   for (;;)
      if (fwrite("Foo", 3, 1, stdout) != 1)
         ;
}

版本 2:

#include <stdio.h>
int main(void)
{
   for (;;)
   {
      if (fwrite("Foo", 3, 1, stdout) != 1)
         ;
   }
}

因此,实际问题是在空语句上遇到断点,其中 if 条件被评估为 false。

这不是“失败”:观察到的程序行为是相同的,编译器可能发出任何指令来匹配观察到的行为。启用的优化越多,编译器就越能“改造”程序。

有一种解决方法可以插入 __nop() 内在函数。编译器会发出一字节的无目的指令,但不会忽略它,并且会使控制流公平。这是拥有编译器不会优化掉的东西的最轻量级方法。

#include <stdio.h>
#include <intrin.h>

int main(void)
{
    for (;;)
        if (fwrite("Foo", 3, 1, stdout) != 1)
            __nop();
}

请注意,将此内在函数添加到程序中可能会使代码的优化程度略有下降,这主要不是由额外的指令引起的,而是由于限制了编译器转换程序造成的。对于您的情况,编译器很可能会丢弃整个 != 1 比较,但不会对 __nop().

进行比较