Reputation: 793
Configuration: Win10 64-bit, VS2019 with all updates and Clang v12.0 installed, and a breakpoint set on the null statement.
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. Why does a breakpoint cause the first version to fail with the VS compiler?
Version 1:
#include <stdio.h>
int main(void)
{
for (;;)
if (fwrite("Foo", 3, 1, stdout) != 1)
;
}
Version 2:
#include <stdio.h>
int main(void)
{
for (;;)
{
if (fwrite("Foo", 3, 1, stdout) != 1)
;
}
}
Upvotes: 1
Views: 112
Reputation: 13719
So, the actual issue is hitting breakpoint on empty statement, where if
condition is evaluated to 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. 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()
.
Upvotes: 1