简体   繁体   English

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

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

Configuration: Win10 64-bit, VS2019 with all updates and Clang v12.0 installed, and a breakpoint set on the null statement.配置:Win10 64位,安装所有更新的VS2019和Clang v12.0,在null语句设置断点。

If compile with the VS compiler, the first version of the code below hits the breakpoint after Foo is output to the console the first time, but loops as expected if compiled with Clang. The second version loops as expected with both the VS compiler and Clang. If I remove the breakpoint both versions loop as expected with both compilers.如果使用 VS 编译器编译,下面的代码的第一个版本在 Foo 是 output 之后第一次到达控制台时遇到断点,但如果使用 Clang 编译则按预期循环。第二个版本按预期使用 VS 编译器和 Clang 循环. 如果我删除断点,两个版本都按预期使用两个编译器循环。 Why does a breakpoint cause the first version to fail with the VS compiler?为什么断点会导致第一个版本在 VS 编译器中失败?

Version 1:版本 1:

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

Version 2:版本 2:

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

So, the actual issue is hitting breakpoint on empty statement, where if condition is evaluated to false.因此,实际问题是在空语句上遇到断点,其中if条件被评估为 false。

It is not a "fail": the observed program behavior is the same, and compiler may emit whatever instructions to match the observed behavior.这不是“失败”:观察到的程序行为是相同的,编译器可能会发出任何指令来匹配观察到的行为。 The more optimizations are enabled, the more compiler would "transform" the program.启用的优化越多,编译器就越能“改造”程序。

There's a workaround to insert __nop() intrinsic.有一种解决方法可以插入__nop()内在函数。 The compiler will emit one-byte purpose-less instruction, but it will not omit it, and will make control flow fair.编译器会发出一字节的无目的指令,但不会忽略它,并且会使控制流公平。 This is the most lightweight way to have something that compiler won't optimize away.这是拥有编译器不会优化掉的东西的最轻量级方法。

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

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

Note that adding this intrinsic into a program may make the code slightly less optimal, and it would be mostly caused not by extra instruction, but by limiting the compiler in transforming program.请注意,将此内在函数添加到程序中可能会使代码的优化程度略有下降,这主要不是由额外指令引起的,而是通过限制编译器转换程序造成的。 For your case, compiler is very likely to throw away the whole != 1 comparison, but it won't do that with __nop() .对于您的情况,编译器很可能会丢弃整个!= 1比较,但它不会用__nop()这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM