Curious
Curious

Reputation: 21510

Are initialized values guaranteed to be reflected through their own address regardless of memory ordering

Following up to this question - std::memory_order_relaxed and initialization. Suppose I have code like this

class Something {
public:
  int value;
};
auto&& pointer = std::atomic<Something*>{nullptr};

// thread 1
auto value = Something{1};
pointer.set(&value, std::memory_order_relaxed);

// thread 2
Something* something = nullptr;
while (!(something = pointer.load(std::memory_order_relaxed))) {}
cout << something->value << endl;

Is this guaranteed to print 1? Can an implementation be allowed to take the address of a non initialized value?

(Assuming that there are no lifetime issues with thread 2 reading the pointer set by thread 1)

Upvotes: 1

Views: 107

Answers (1)

nmr
nmr

Reputation: 16849

No, it isn't guaranteed to print 1. The write to the field value may be reordered WRT to the write to pointer. If it is reordered to after the write to pointer, 'thread 2' will observe uninitialized memory.

This can and does happen in practice on ARM.

Because x86 CPUs maintain "total store order" (i.e. all stores are observable by other threads in the order they were issued by the issuing thread,) the CPU cannot cause this to happen. But, it still can happen on x86 because, while the CPU will not reorder writes, the compiler is allowed to reorder writes. I don't know if in practice compilers do that.

Upvotes: 2

Related Questions