根据输出的信息,任何人都可以解释以下代码吗?
(a==1 && a==2 && a==3)怎么都正确?

#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;
    }
  }
}

输出:



...

2019年一月

我认为这个问题与该链接-> C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?高度相关

最佳答案

您正在遇到未定义的行为。

您的代码具有竞争条件;一个线程正在读取a,而另一个线程正在写入,因此不会发生同步。您不得在C++中执行此操作。可以将执行此操作的程序编译为可以执行任何操作。

实际上,在发行版上,我希望可以将其编译为if(false)。编译器优化主线程,不注意同步,证明a没有UB不能是3个不同的值,并优化if

在调试版本上,我可以预期到您看到的症状。不是因为它更正确,而是因为调试版本往往不会因这种未定义的行为而跳闸。

因此,合理讨论程序的第一件事是删除未定义的行为:使a成为std::atomic<int>而不是int

现在,在发行版和调试中,您都希望看到……正是您的测试显示的内容。或者什么都没有。或两者之间的任何东西。结果不再是不确定的,而是不确定的。
if语句不是原子的。在这些条件之间,a可以更改。随着程序永远运行,它有时应该会发生,因为另一个线程正在对其进行更改。

生成的程序定义良好。 Even forward progress guarantees可以,因为您读取了原子变量。

关于c++ - 谁能解释((a == 1 && a == 2 && a == 3)== true)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52613308/

10-17 00:18