Date: Fri, 12 Jun 2026 17:41:09 +0800
>
> The abstract machine doesn’t do anything! It doesn’t exist!
If the abstract machine doesn't exist, how do you know what the possible
observable behaviors are for a given program?
It is not defined! That’s what we have been telling you with all these
> emails.
>
[intro.abstract] p1 says
> The semantic descriptions in this document define a parameterized
nondeterministic abstract machine.This document places no requirement on
the structure of conforming implementations.
In particular, they need not copy or emulate the structure of the abstract
machine.Rather, conforming implementations are required to emulate (only)
the observable behavior of the abstract machine as explained below.
So, the abstract machine does specify what the observable behavior of a
given program is, according to the semantics described in the C++'s
document.
On Fri, Jun 12, 2026 at 5:36 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:
> > This is not what an abstract machine does.
>
>
>
> The abstract machine doesn’t do anything! It doesn’t exist!
>
>
>
>
>
> > All semantics and structures defined in the abstract machine
>
>
>
> It is not defined! That’s what we have been telling you with all these
> emails.
>
>
>
>
>
>
>
> *From:* jim x <xmh970252187_at_[hidden]>
> *Sent:* Friday, June 12, 2026 11:29
> *To:* Jennifier Burnett <jenni_at_[hidden]>
> *Cc:* jim x via Std-Discussion <std-discussion_at_[hidden]>; Tiago
> Freire <tmiguelf_at_[hidden]>
> *Subject:* Re: [std-discussion] Does the C++ abstract machine recognize a
> temporal order of execution?
>
>
>
> This doesn't enforce sequential execution however, since the abstract
> machine is allowed to time travel and see what the result will be and
> execute the second statement using that value before it executes the first.
>
>
>
> This is not what an abstract machine does; instead, it's what a conforming
> implementation can do. All semantics and structures defined in the abstract
> machine aren't changed or reordered; they're used to infer the observable
> behavior.
>
>
>
> On Fri, Jun 12, 2026 at 4:45 PM Jennifier Burnett <jenni_at_[hidden]>
> wrote:
>
> > 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?
>
> To summarise the rest of the thread: VLIW hardware and OoO hardware will
> allow executing instructions that correspond to two different statements at
> the same time. The standard only requires that if one statement
> happens-before another statement, the results of the first statement must
> be visible to the second. This doesn't enforce sequential execution
> however, since the abstract machine is allowed to time travel and see what
> the result will be and execute the second statement using that value before
> it executes the first.
>
> The ultimate point is: if an execution produces the same results as
> sequential execution, it's allowed even if the execution is not itself
> sequential.
>
> Once multiple threads get involved things get a bit wibbly, but that's due
> to inter-thread visibility issues rather than anything to do with
> single-threaded semantics.
>
>
>
> On 12 June 2026 07:17:16 BST, jim x via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
>
> 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
>
>
>
>
> The abstract machine doesn’t do anything! It doesn’t exist!
If the abstract machine doesn't exist, how do you know what the possible
observable behaviors are for a given program?
It is not defined! That’s what we have been telling you with all these
> emails.
>
[intro.abstract] p1 says
> The semantic descriptions in this document define a parameterized
nondeterministic abstract machine.This document places no requirement on
the structure of conforming implementations.
In particular, they need not copy or emulate the structure of the abstract
machine.Rather, conforming implementations are required to emulate (only)
the observable behavior of the abstract machine as explained below.
So, the abstract machine does specify what the observable behavior of a
given program is, according to the semantics described in the C++'s
document.
On Fri, Jun 12, 2026 at 5:36 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:
> > This is not what an abstract machine does.
>
>
>
> The abstract machine doesn’t do anything! It doesn’t exist!
>
>
>
>
>
> > All semantics and structures defined in the abstract machine
>
>
>
> It is not defined! That’s what we have been telling you with all these
> emails.
>
>
>
>
>
>
>
> *From:* jim x <xmh970252187_at_[hidden]>
> *Sent:* Friday, June 12, 2026 11:29
> *To:* Jennifier Burnett <jenni_at_[hidden]>
> *Cc:* jim x via Std-Discussion <std-discussion_at_[hidden]>; Tiago
> Freire <tmiguelf_at_[hidden]>
> *Subject:* Re: [std-discussion] Does the C++ abstract machine recognize a
> temporal order of execution?
>
>
>
> This doesn't enforce sequential execution however, since the abstract
> machine is allowed to time travel and see what the result will be and
> execute the second statement using that value before it executes the first.
>
>
>
> This is not what an abstract machine does; instead, it's what a conforming
> implementation can do. All semantics and structures defined in the abstract
> machine aren't changed or reordered; they're used to infer the observable
> behavior.
>
>
>
> On Fri, Jun 12, 2026 at 4:45 PM Jennifier Burnett <jenni_at_[hidden]>
> wrote:
>
> > 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?
>
> To summarise the rest of the thread: VLIW hardware and OoO hardware will
> allow executing instructions that correspond to two different statements at
> the same time. The standard only requires that if one statement
> happens-before another statement, the results of the first statement must
> be visible to the second. This doesn't enforce sequential execution
> however, since the abstract machine is allowed to time travel and see what
> the result will be and execute the second statement using that value before
> it executes the first.
>
> The ultimate point is: if an execution produces the same results as
> sequential execution, it's allowed even if the execution is not itself
> sequential.
>
> Once multiple threads get involved things get a bit wibbly, but that's due
> to inter-thread visibility issues rather than anything to do with
> single-threaded semantics.
>
>
>
> On 12 June 2026 07:17:16 BST, jim x via Std-Discussion <
> std-discussion_at_[hidden]> wrote:
>
> 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 09:41:27
