# How to achieve a StoreLoad barrier in C++11?

Options A and B are valid solutions.

- Option A: it doesn't really matter what a seq-cst fence translates to, the C++ standard clearly defines what guarantees it provides. I have laid them out in this post: When is a memory_order_seq_cst fence useful?
- Option B: yes, your reasoning is correct. All modifications on some object have a single total order (the modification order), so you can use that to synchronize the threads and ensure visibility of all side-effects.

However, Option C is *not* valid! A synchronize-with relation can only be established by acquire/release-operations *on the same object*. In your case you have two completely different and indepent objects `dummy1`

and `dummy2`

. But these cannot be used to establish a happens-before relation. In fact, since the atomic variables are purely local (i.e., they are only ever touched by one thread), *the compiler is free to remove them based on the as-if rule*.

**Update**

**Option A:**

I assume `set()`

and `check()`

do operate on some atomic value. Then we have the following situation (-> denotes *sequenced-before*):

`set()`

->`fence1(seq_cst)`

->`y.load()`

`y.store(true)`

->`fence2(seq_cst)`

->`check()`

So we can apply the following rule:

For atomic operations

AandBon an atomic objectM, whereAmodifiesMandBtakes its value, if there are`memory_order_seq_cst`

fencesXandYsuch thatAis sequenced beforeX,Yis sequenced beforeB, andXprecedesYinS, thenBobserves either the effects ofAor a later modification ofMin its modification order.

I.e., either `check()`

sees that value stored in `set`

, or `y.load()`

sees the value written be `y.store()`

(the operations on `y`

can even use `memory_order_relaxed`

).

**Option C:**

The C++17 standard states [32.4.3, p1347]:

There shall be a single total order

Son all`memory_order_seq_cst`

operations, consistent with the "happens before" order and modification orders for all affected locations [...]

The important word here is "consistent". It implies that if an operation *A* happens-before an operation *B*, then *A* must precede *B* in *S*. However, logical implication is a one-way-street, so we cannot infer the inverse: just because some operation *C* precedes an operation *D* in *S* does not imply that *C* happens before *D*.

**In particular, two seq-cst operations on two separate objects cannot be used to establish a happens before relation, even though the operations are totally ordered in S.** If you want to order operations on separate objects, you have to refer to seq-cst-fences (see Option A).