This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4321. How are evaluations occurring within a store and a load operation ordered where the store synchronized with the load

Section: 32.5.8.2 [atomics.types.operations] Status: New Submitter: jim x Opened: 2025-08-20 Last modified: 2025-08-25

Priority: Not Prioritized

View other active issues in [atomics.types.operations].

View all other issues in [atomics.types.operations].

View all issues with New status.

Discussion:

Consider this example:

std::atomic<int> v = 0;
// thread 1:
v.store(1, memory_order::release); // #1
// thread 2:
v.load(memory_order::acquire); // #2

Say, #2 reads the value written by #1, #1 synchronizes with #2. According to 6.10.2.2 [intro.races] p7:

An evaluation A happens before an evaluation B (or, equivalently, B happens after A) if either

  1. (7.1) — […]

  2. (7.2) — A synchronizes with B, or

  3. (7.3) — […]

So, #1 happens before B. However, 6.10.1 [intro.execution] p12 says:

For each

  1. (12.1) — function invocation,

  2. (12.2) — […]

  3. (12.3) — […]

F, each evaluation that does not occur within F but is evaluated on the same thread and as part of the same signal handler (if any) is either sequenced before all evaluations that occur within F or sequenced after all evaluations that occur within F;

Because both v.store(...) and v.load(...) are function invocations, and we can think that the member functions comprise some evaluations to form the operation, therefore, how are these evaluations that occur within the store ordered with those within the load?

The rule only says the store synchronizes with the load, hence, the evaluation of the function call expression v.store(...) happens before the evaluation of the function call expression v.load(...), but how about these evaluations occurring within these functions?

A possible resolution might be: The order between all evaluations occurring within a function invocation and another evaluation B is determined by how the evaluation of the function call expression is ordered in relation to the expression B.

For example, if v.store() happens-before E, then all evaluations occurring within the store happen-before E. As well, v.store(...) synchronizes with v.load(...), then all evaluations occurring within v.store(...) synchronize with all evaluations occurring within v.load(...).

Proposed resolution: