Hello, When I compile the following C++ code ========================================== extern int f(void); struct A { int x; A() { this->x = f(); } }; int g(void) { static A a; return a.x; } ========================================== with "g++ -fdump-tree-gimple" (with gcc 4.5.0) on x86-64, the generated GIMPLE code is like this: ========================================== int g() () { char * _ZGVZ1gvE1a.0; char D.2126; bool retval.1; int D.2130; bool D.2123; int D.2138; static struct A a; _ZGVZ1gvE1a.0 = (char *) &_ZGVZ1gvE1a; D.2126 = *_ZGVZ1gvE1a.0; if (D.2126 == 0) goto <D.2127>; else goto <D.2128>; <D.2127>: [__cxa_acquire etc. snipped] <D.2128>: <D.2137>: D.2138 = a.x; return D.2138; } ========================================== If I'm understanding correctly, to be thread-safe, double-checked locking in general requires a load barrier between checking the guard variable and accessing the object. On x86-64 no CPU-level load barrier is necessary, but shouldn't one be needed at the compiler level? Here the guard variable *_ZGBZ1gvE1a.0 is not marked volatile, so can't the compiler later move the load of a.x before the load of the guard variable (and redo it if we go the D.2127 path)? This would clearly be unsafe, as another thread can do the construction after the first load of a.x and before loading the guard variable, so the current thread would see object "a" constructed but will be returning a stale uninitialized copy of a.x. Please CC me as I'm not subscribed. r6144