Possible error of the VS2012 compiler (perhaps when optimizing the entire program?)

Could this be a compiler error? My environment:

  • Win7 pro (64-bit)
  • VS2012 (Update 3)

I compile a tiny console program below. Everything works fine for unpacking / debugging in 64 bit. The x32 debug build also works great. In the x32 build, "BUG!" Is displayed.

If I turn off "Optimization of the whole program", which will fix the problem.

Any ideas?

-

#include <string> #include <iostream> int main() { std::string const buffer = "hello, world"; std::string::size_type pos = 0; std::string::size_type previous_pos; while (pos != std::string::npos) { previous_pos = ++pos; pos = buffer.find('w', pos); } if (previous_pos == std::string::npos) { std::cout << "BUG!!"<< std::endl; } return 0; } 
+4
source share
1 answer

I can reproduce this too. When an error occurs, the code tests eax to determine whether to output "BUG", which is the same register as for "pos".

 17: previous_pos = ++pos; 

013C12E5 inc eax
...

 21: if (previous_pos == std::string::npos) 

00301345 cmp eax, eax
00301347 jne main + 0F6h (0301366h)

However, if you make changes to try to make the optimizer realize that they are different, then the test is different. If I add ++ previous_pos to the end of the loop body, then it uses ecx for previous_pos and the error will disappear:

 22: if (previous_pos == std::string::npos) 

00361349 cmp ecx, eax
0036134B jne main + 0FAh (036136Ah)

If I changed find to 'pos = buffer.find (' w ', previous_pos); (search from previous_pos instead of pos, which has the same meaning), then it uses ebx, and again the error disappears:

 21: if (previous_pos == std::string::npos) 

00191345 cmp ebx, eax
00191347 jne main + 0F6h (0191366h)

So, in the original it seems that the optimizer mistakenly decides that it can use eax for both of these variables, despite the string 'pos = buffer.find (' w ', pos); which can set pos to a different value than previous_pos.

+4
source

Source: https://habr.com/ru/post/1495236/


All Articles