在 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 <atomic> #include <thread> #include <cstdio> char const* foo() { static ::std::atomic<char const*> 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
Attachment:
OpenPGP_signature
Description: OpenPGP digital signature