Suppose my code is like the following:
struct Foo {
Foo() : x(10) {}
int x_;
}
void WillRunInThread(const Foo* f) {
cout << "f.x_ is: " << f->x_ << endl;
}
struct Baz {
Baz() : foo_(), t_(&WillRunInThread, &foo_) {}
Foo foo_;
std::thread t_;
}
int main(int argc, char** argv) {
Baz b;
b.t_.join();
}
Am I guaranteed that WillRunInThread
will print 10? I have seen some StackOverflow answers that indicate this is safe. However, I'm not sure that's the case. Specifically, I think the following two possibilities exist both of which could create issues:
Foo.x_
could be stored in a register whent_
is started.- The compiler could re-order some instructions. While C++ guarantees that
foo_
will appear to be constructed beforet_
that's only within the same thread. The compiler is free to, for example, re-order the initialization offoo_.x_
until aftert_
.
I see no indication that std::thread
's constructor acts as a memory fence of any kind to prevent the above two issues. However, I see code like the above quite frequently which makes me think I'm missing something. Any clarification would be appreciated.