在 2021-01-12 22:20, Jonathan Wakely via Gcc-help 写道: > > I'm not sure about the rules for C, but in C++ the compiler can assume > there is no race, because the increment is not atomic. If there were > another access to the variable then a non-atomic store would be a race > even in the bar1 version. > What about this code: // -- beginning of copy-n-pasted code char const* foo(); int cursor = 0; char const* bar1() { char const* result = foo(); if (result) ++cursor; return result; } char const* bar2() { char const* result = foo(); cursor += !!result; return result; } // -- end of copy-n-pasted code #include #include #include char const* foo() { static ::std::atomic str("meow"); return str.exchange(nullptr); } int main() { ::std::thread thrs[10]; for(auto& r : thrs) r = ::std::thread(bar1); for(auto& r : thrs) r.join(); ::std::printf("cursor = %d\n", cursor); } `foo()` will return non-null for exactly one thread. Increment of `cursor` by that thread is sequenced before its termination, which synchronizes with exactly one `join()`, which is sequenced before the final read of `cursor`. There is no race in this program, but there would be if `bar2` was called in place of `bar1`, where all threads could modify `cursor` concurrently. -- Best regards, LH_Mouse