On Tue, 12 Jan 2021, 16:55 Liu Hao, <lh_mouse@xxxxxxx> wrote: > 在 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. > Yes, that's Florian's point. Introducing a write in the other threads would introduce a data race, which has undefined behaviour.