Can anyone explain how ((a == 1 && a == 2 && a == 3) == true)?

  • A+
Category:Languages

Based on the info of the output, can anyone explains the code below?

How can all of (a==1 && a==2 && a==3) be true?

#include <iostream> #include <thread>  int a = 0;  int main() {   std::thread runThread([]() { while (true) { a = 1; a = 2; a = 3; }});   while (true)   {     if (a == 1 && a == 2 && a == 3)     {       std::cout << "Hell World!" << std::endl;     }   } } 

Output:

Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! Hell World! 

...

 


You are experiencing undefined behavior.

Your code has a race condition; one thread is reading a while another is writing, and no synchronization occurs. You aren't allowed to do this in C++. Programs that do that can be compiled to do anything at all.

In fact, on a release build, I'd expect that to compile down to if(false). The compiler optimizes the main thread, notices no synchronization, proves that a cannot be 3 different values without UB, and optimizes out the if.

On a debug build, I could expect the symptoms you see. Not because it is more correct, but because debug builds tend not to trip over that kind of undefined behavior.

So the first thing you have to do to talk about your program reasonably is remove the undefined behavior: make a a std::atomic<int> instead of an int.

Now in both release and debug you'd expect to see ... exactly what your test showed. Or nothing. Or anything in between. The result is no longer undefined, but it remains non-deterministic.

The if statement isn't atomic. Between the conditions, a can change. And with a program running forever it should happen sometimes, as the other thread is changing it.

The resulting program is well defined. Even forward progress guarantees are ok, because you read an atomic variable.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: