Date: Fri, 12 Jun 2026 14:17:16 +0800
>
> But there’s nothing else to debate here. We already explained what
> behavior you can expect with this.
However, the question in my OP is not about observable behavior. I talked
about that, for two evaluations `A` and `B`, whether the control flow
executes `A` at a point in time that is no later than when it executes `B`
is a valid semantics in the abstract machine? Of course, a real
implementation doesn't need to emulate the semantics of the abstract
machine.
On Fri, Jun 12, 2026 at 2:09 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:
>
>
> > The OP is talking about the semantics and structure in the abstract
> machine, not only the observable behavior. A possible observable behavior
> is justified as valid since we infer that from the semantics and structure
> in the abstract machine. So, talking about whether this is a valid
> semantics in the abstract machine is necessary.
>
>
>
> You already got your answer! That is the answer to what the “abstract
> machine” is expected to do. What else do you want?
>
>
>
> The concept of the “abstract machine” is only about how the code should be
> interpreted, it is not an emulator that you should create, and it does not
> define everything.
>
>
>
> The “abstract machine” allows for unspecified behavior; but code must run
> on real machines and on real machines something must always happen.
>
> On some devices the result of the load will always going to be 1, on
> others it sometimes is going to be 0.
>
> And the “abstract machine” is not going to tell you which one is right, it
> just shrugs its shoulders and says “yes”. Because different systems do
> different things, and this is allowed. And this is especially the case for
> multi-threaded systems.
>
>
>
> You can call it an “incomplete non-deterministic abstract machine” if you
> want to be more exact.
>
>
>
> But there’s nothing else to debate here. We already explained what
> behavior you can expect with this.
>
> All of your questions have been answered.
>
>
>
> If you still think that there is still an open question, there’s nothing I
> can do to help you. My capacity for explaining things is limited and I
> can’t make it understand it on your behalf.
>
>
>
>
>
> *From:* jim x <xmh970252187_at_[hidden]>
> *Sent:* Friday, June 12, 2026 04:45
> *To:* Tiago Freire <tmiguelf_at_[hidden]>
> *Cc:* std-discussion_at_[hidden]
> *Subject:* Re: [std-discussion] Does the C++ abstract machine recognize a
> temporal order of execution?
>
>
>
> In your OP example if you find that 'now1 < now2', the result of the
> atomic load being 0 is a valid outcome.
>
>
>
> Yeah, I keep agreeing that this is a valid possible execution in the
> abstract machine.
>
>
>
> I believe you got lost in nuances of distinctions without a difference.
>
>
>
> The OP is talking about the semantics and structure in the abstract
> machine, not only the observable behavior. A possible observable behavior
> is justified as valid since we infer that from the semantics and structure
> in the abstract machine.
>
>
>
> So, talking about whether this is a valid semantics in the abstract
> machine is necessary.
>
>
>
> On Thu, Jun 11, 2026 at 6:33 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:
>
> I keep repeating and I don't think you understand what we are saying.
>
>
>
> In your OP example if you find that 'now1 < now2', the result of the
> atomic load being 0 is a valid outcome.
>
>
>
> I believe you got lost in nuances of distinctions without a difference.
>
>
>
> Discussing anything else is pointless regardless of whatever it is you
> hope to practically achieve with this question.
>
>
> ------------------------------
>
> *From:* Std-Discussion <std-discussion-bounces_at_[hidden]> on
> behalf of jim x via Std-Discussion <std-discussion_at_[hidden]>
> *Sent:* Thursday, June 11, 2026 11:16:57 AM
> *To:* Jennifier Burnett <jenni_at_[hidden]>
> *Cc:* jim x <xmh970252187_at_[hidden]>; std-discussion_at_[hidden] <
> std-discussion_at_[hidden]>
> *Subject:* Re: [std-discussion] Does the C++ abstract machine recognize a
> temporal order of execution?
>
>
>
>
>
> so the question of whether one statement executes before another on a
> machine that doesn't exist and will never execute the code is vacuous. You
> need to provide a visible outcome that you are expecting to be possible or
> not possible on the hypothetical machine.
>
>
>
> The structure and semantics inside the abstract machine are not
> necessarily preserved in the observable behavior, but they are an important
> part of reasoning about possible execution outcomes. For instance, the
> modification order of an atomic object is only the semantic inside the
> abstract machine, and it is not the observable behavior; It is because of
> its existence that we know what the legitimate possible executions in the
> abstract machine are for a multi-threaded program.
>
>
>
> On Thu, Jun 11, 2026 at 4:03 PM Jennifier Burnett <jenni_at_[hidden]>
> wrote:
>
> I think in this case we're somewhat losing the forest for the trees. How
> exactly would you test if #1 occurred before #2? The abstract machine is,
> well, abstract. It doesn't exist and is meaningful only in the possible
> executions it can allow, so the question of whether one statement executes
> before another on a machine that doesn't exist and will never execute the
> code is vacuous. You need to provide a visible outcome that you are
> expecting to be possible or not possible on the hypothetical machine.
>
>
>
> On 11 June 2026 08:46:43 BST, jim x <xmh970252187_at_[hidden]> wrote:
>
> In the OP, I don't think `#1` must be visible to `#4` when `now1 < now2`.
> As I said above, the visibility is guaranteed by the happens-before that
> has a strict definition in the specification. To avoid over-focus on the
> inter-thread happens-before, I think the original question can be
> simplified as an example that only comprises a single thread.
>
> ````cpp
>
> #include <atomic>
>
> #include <chrono>
>
>
>
> std::atomic<int> val = 0;
>
> int main(){
>
> val.store(1,std::memory_order::relaxed); // #1
>
> auto c1 = std::chrono::steady_clock::now(); // #2
>
> }
>
> ````
>
> The control flow first executes `#1`, then `#2`, while the control flow
> executing `#2` samples a global time point. So, the question is: Is `#1`
> executed by the control flow at a point in time that is no later than the
> time point represented by `c1`? Note that we only talk about this question
> in the abstract machine.
>
>
>
> On Thu, Jun 11, 2026 at 3:22 PM Jennifier Burnett <jenni_at_[hidden]>
> wrote:
>
> Happens-before is very relevant because the question is about visibility
> between threads. The sequencing of statements in c++ is defined by the
> sequenced-before relation, which is implicitly upgraded to a happens-before
> relationship. The OP is asking if a write on one thread must become visible
> to a read on another thread if the latter observes a later time point from
> a call that is sequenced-before the read than the prior does from a call
> that is sequenced-after the write. Without a happens-before relationship
> between the read and the write that simply isn't possible because of
> trivial hardware optimisations like store buffering. Just because an
> execution on one thread happens temporally after an execution on another
> thread does not necessarily mean that the later execution has the same view
> of memory that the earlier one does.
>
> My point is that unless you consider that observing a time point counts as
> a type of write there's no way of establishing the release part of the
> acquire-release relationship that's required for creating the
> happens-before.
>
>
>
> On 11 June 2026 06:51:46 BST, jim x <xmh970252187_at_[hidden]> wrote:
>
>
>
> What exactly would you be establishing a happens-before relationship with
> in the original example?
>
>
>
> This is the misunderstanding of the OP. The OP doesn't talk about the
> happens-before relationship; instead, the intention can be simplified as
> talking about whether the control flow executing a previous expression
> occurs in no later time point than the time point it executes a later
> expression.
>
>
>
> On Thu, Jun 11, 2026 at 1:37 PM Jennifier Burnett via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
>
> An acquire barrier is meaningless in this context. An acquire barrier
> needs either a release operation or atomic operation preceded by a release
> barrier to have any semantics beyond relaxed. What exactly would you be
> establishing a happens-before relationship with in the original example?
> Assuming the call to now() is an implicit acquire barrier changes nothing
> about the semantics because there's no corresponding release for it to
> establish a happens-before relationship with. The first thread doesn't even
> have any operations other than the call to now() that the acquire barrier
> would apply to
>
> On 11 June 2026 01:37:42 BST, Thiago Macieira via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
> >On Wednesday, 10 June 2026 16:24:30 Pacific Daylight Time Simon Cooke
> wrote:
> >> If you don't want that, you need acquire semantics, which will prevent
> the
> >> write from down after the timestamp() call in #2
> >
> >This is the essence of the argument: reading from the monotonic clock
> should
> >be an acquire barrier. The Standard does not say it is, but I think it
> should.
> >
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
>
>
>
> But there’s nothing else to debate here. We already explained what
> behavior you can expect with this.
However, the question in my OP is not about observable behavior. I talked
about that, for two evaluations `A` and `B`, whether the control flow
executes `A` at a point in time that is no later than when it executes `B`
is a valid semantics in the abstract machine? Of course, a real
implementation doesn't need to emulate the semantics of the abstract
machine.
On Fri, Jun 12, 2026 at 2:09 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:
>
>
> > The OP is talking about the semantics and structure in the abstract
> machine, not only the observable behavior. A possible observable behavior
> is justified as valid since we infer that from the semantics and structure
> in the abstract machine. So, talking about whether this is a valid
> semantics in the abstract machine is necessary.
>
>
>
> You already got your answer! That is the answer to what the “abstract
> machine” is expected to do. What else do you want?
>
>
>
> The concept of the “abstract machine” is only about how the code should be
> interpreted, it is not an emulator that you should create, and it does not
> define everything.
>
>
>
> The “abstract machine” allows for unspecified behavior; but code must run
> on real machines and on real machines something must always happen.
>
> On some devices the result of the load will always going to be 1, on
> others it sometimes is going to be 0.
>
> And the “abstract machine” is not going to tell you which one is right, it
> just shrugs its shoulders and says “yes”. Because different systems do
> different things, and this is allowed. And this is especially the case for
> multi-threaded systems.
>
>
>
> You can call it an “incomplete non-deterministic abstract machine” if you
> want to be more exact.
>
>
>
> But there’s nothing else to debate here. We already explained what
> behavior you can expect with this.
>
> All of your questions have been answered.
>
>
>
> If you still think that there is still an open question, there’s nothing I
> can do to help you. My capacity for explaining things is limited and I
> can’t make it understand it on your behalf.
>
>
>
>
>
> *From:* jim x <xmh970252187_at_[hidden]>
> *Sent:* Friday, June 12, 2026 04:45
> *To:* Tiago Freire <tmiguelf_at_[hidden]>
> *Cc:* std-discussion_at_[hidden]
> *Subject:* Re: [std-discussion] Does the C++ abstract machine recognize a
> temporal order of execution?
>
>
>
> In your OP example if you find that 'now1 < now2', the result of the
> atomic load being 0 is a valid outcome.
>
>
>
> Yeah, I keep agreeing that this is a valid possible execution in the
> abstract machine.
>
>
>
> I believe you got lost in nuances of distinctions without a difference.
>
>
>
> The OP is talking about the semantics and structure in the abstract
> machine, not only the observable behavior. A possible observable behavior
> is justified as valid since we infer that from the semantics and structure
> in the abstract machine.
>
>
>
> So, talking about whether this is a valid semantics in the abstract
> machine is necessary.
>
>
>
> On Thu, Jun 11, 2026 at 6:33 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:
>
> I keep repeating and I don't think you understand what we are saying.
>
>
>
> In your OP example if you find that 'now1 < now2', the result of the
> atomic load being 0 is a valid outcome.
>
>
>
> I believe you got lost in nuances of distinctions without a difference.
>
>
>
> Discussing anything else is pointless regardless of whatever it is you
> hope to practically achieve with this question.
>
>
> ------------------------------
>
> *From:* Std-Discussion <std-discussion-bounces_at_[hidden]> on
> behalf of jim x via Std-Discussion <std-discussion_at_[hidden]>
> *Sent:* Thursday, June 11, 2026 11:16:57 AM
> *To:* Jennifier Burnett <jenni_at_[hidden]>
> *Cc:* jim x <xmh970252187_at_[hidden]>; std-discussion_at_[hidden] <
> std-discussion_at_[hidden]>
> *Subject:* Re: [std-discussion] Does the C++ abstract machine recognize a
> temporal order of execution?
>
>
>
>
>
> so the question of whether one statement executes before another on a
> machine that doesn't exist and will never execute the code is vacuous. You
> need to provide a visible outcome that you are expecting to be possible or
> not possible on the hypothetical machine.
>
>
>
> The structure and semantics inside the abstract machine are not
> necessarily preserved in the observable behavior, but they are an important
> part of reasoning about possible execution outcomes. For instance, the
> modification order of an atomic object is only the semantic inside the
> abstract machine, and it is not the observable behavior; It is because of
> its existence that we know what the legitimate possible executions in the
> abstract machine are for a multi-threaded program.
>
>
>
> On Thu, Jun 11, 2026 at 4:03 PM Jennifier Burnett <jenni_at_[hidden]>
> wrote:
>
> I think in this case we're somewhat losing the forest for the trees. How
> exactly would you test if #1 occurred before #2? The abstract machine is,
> well, abstract. It doesn't exist and is meaningful only in the possible
> executions it can allow, so the question of whether one statement executes
> before another on a machine that doesn't exist and will never execute the
> code is vacuous. You need to provide a visible outcome that you are
> expecting to be possible or not possible on the hypothetical machine.
>
>
>
> On 11 June 2026 08:46:43 BST, jim x <xmh970252187_at_[hidden]> wrote:
>
> In the OP, I don't think `#1` must be visible to `#4` when `now1 < now2`.
> As I said above, the visibility is guaranteed by the happens-before that
> has a strict definition in the specification. To avoid over-focus on the
> inter-thread happens-before, I think the original question can be
> simplified as an example that only comprises a single thread.
>
> ````cpp
>
> #include <atomic>
>
> #include <chrono>
>
>
>
> std::atomic<int> val = 0;
>
> int main(){
>
> val.store(1,std::memory_order::relaxed); // #1
>
> auto c1 = std::chrono::steady_clock::now(); // #2
>
> }
>
> ````
>
> The control flow first executes `#1`, then `#2`, while the control flow
> executing `#2` samples a global time point. So, the question is: Is `#1`
> executed by the control flow at a point in time that is no later than the
> time point represented by `c1`? Note that we only talk about this question
> in the abstract machine.
>
>
>
> On Thu, Jun 11, 2026 at 3:22 PM Jennifier Burnett <jenni_at_[hidden]>
> wrote:
>
> Happens-before is very relevant because the question is about visibility
> between threads. The sequencing of statements in c++ is defined by the
> sequenced-before relation, which is implicitly upgraded to a happens-before
> relationship. The OP is asking if a write on one thread must become visible
> to a read on another thread if the latter observes a later time point from
> a call that is sequenced-before the read than the prior does from a call
> that is sequenced-after the write. Without a happens-before relationship
> between the read and the write that simply isn't possible because of
> trivial hardware optimisations like store buffering. Just because an
> execution on one thread happens temporally after an execution on another
> thread does not necessarily mean that the later execution has the same view
> of memory that the earlier one does.
>
> My point is that unless you consider that observing a time point counts as
> a type of write there's no way of establishing the release part of the
> acquire-release relationship that's required for creating the
> happens-before.
>
>
>
> On 11 June 2026 06:51:46 BST, jim x <xmh970252187_at_[hidden]> wrote:
>
>
>
> What exactly would you be establishing a happens-before relationship with
> in the original example?
>
>
>
> This is the misunderstanding of the OP. The OP doesn't talk about the
> happens-before relationship; instead, the intention can be simplified as
> talking about whether the control flow executing a previous expression
> occurs in no later time point than the time point it executes a later
> expression.
>
>
>
> On Thu, Jun 11, 2026 at 1:37 PM Jennifier Burnett via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
>
> An acquire barrier is meaningless in this context. An acquire barrier
> needs either a release operation or atomic operation preceded by a release
> barrier to have any semantics beyond relaxed. What exactly would you be
> establishing a happens-before relationship with in the original example?
> Assuming the call to now() is an implicit acquire barrier changes nothing
> about the semantics because there's no corresponding release for it to
> establish a happens-before relationship with. The first thread doesn't even
> have any operations other than the call to now() that the acquire barrier
> would apply to
>
> On 11 June 2026 01:37:42 BST, Thiago Macieira via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
> >On Wednesday, 10 June 2026 16:24:30 Pacific Daylight Time Simon Cooke
> wrote:
> >> If you don't want that, you need acquire semantics, which will prevent
> the
> >> write from down after the timestamp() call in #2
> >
> >This is the essence of the argument: reading from the monotonic clock
> should
> >be an acquire barrier. The Standard does not say it is, but I think it
> should.
> >
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
>
>
>
Received on 2026-06-12 06:17:33
