C++ Logo

std-discussion

Advanced search

Re: Does the C++ abstract machine recognize a temporal order of execution?

From: jim x <xmh970252187_at_[hidden]>
Date: Thu, 11 Jun 2026 10:28:09 +0800
>
> The "as-if" rule is not an implementation detail. I don’t know what do you
> think the "as-if" rule is if not a part of the “abstract machine”.


The *Abstract Machine (AM)* is a formal model that defines the language's
semantics. It executes programs literally to establish the baseline
'observable behavior.' It has no concept of optimization or 'as-if'.

The *'as-if' rule*, on the other hand, is a license granted specifically to
the *conforming implementation* (the compiler). It allows the compiler to
deviate from the step-by-step execution of the AM, provided the final
observable behavior is the same.

If the 'as-if' rule applied to the Abstract Machine itself, it would lead
to circular reasoning: the AM would be behaving 'as if' it were the AM. The
AM is the ground truth; it doesn't need the 'as-if' rule because it is the
standard."

In addition, see the definition of the "as-if" rule


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


This provision is sometimes called the “as-if” rule, because an
implementation is free to disregard any requirement of this document as
long as the result is as if the requirement had been obeyed, as far as can
be determined from the observable behavior of the program. For instance, an
actual implementation need not evaluate part of an expression if it can
deduce that its value is not used and that no side effects affecting the
observable behavior of the program are produced.





On Wed, Jun 10, 2026 at 10:08 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:

>
>
>
>
> I don’t know what you mean.
>
>
>
> The "as-if" rule is not an implementation detail. I don’t know what do you
> think the "as-if" rule is if not a part of the “abstract machine”.
>
> Regardless of what you think the “abstract machine” is, I have raised you
> the practical problem that time consistency is not a thing that still exist
> and it doesn’t matter what language you are talking about, either it be
> C++, C, Rust, assembly, because CPUs no longer work like that.
>
> So, it’s only a matter of implementation of
> “std::chrono::steady_clock::now()”, if it issues hardware instructions to
> force an instruction sequence then time consistency is guaranteed, if it
> doesn’t then it is not.
>
> And in that case if now1 < now2 there is no guarantee that val.load(
> relaxed ); will get you a 1. And this is because if you don’t tell the CPU
> to behave in a certain way it doesn’t have to. This is not a C++ thing.
>
>
>
> *From:* jim x <xmh970252187_at_[hidden]>
> *Sent:* Wednesday, June 10, 2026 15:46
> *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?
>
>
>
> As I said in this subject, we only talk about the question in the *abstract
> machine.* So, how `std::chrono::steady_clock::now()` behaves is only
> according to the relevant rules.
>
>
>
> In general “temporal order of execution” is not a guaranteed thing, only
> “observable effects will be as-if in order in restricted circumstances” are
> guaranteed, but there are some functions/features to explicitly ensure that
> certain things happen in a particular order.
>
>
>
> Again, "as-if" only applies to conforming implementations. We're talking
> about the case in the C++ abstract machine. This is like we talked about
> "sequence-before" in the abstract machine and concluded what the observable
> behavior should be based on the original structure. In this process, we
> don't need to consider reordering; that's the matter of implementations
> under the "as-if" rule.
>
>
>
> On Wed, Jun 10, 2026 at 7:40 PM Tiago Freire <tmiguelf_at_[hidden]> wrote:
>
> For your example, “it depends”, on how std::chrono::steady_clock::now() is
> implemented.
>
>
>
> In general “temporal order of execution” is not a guaranteed thing, only
> “observable effects will be as-if in order in restricted circumstances” are
> guaranteed, but there are some functions/features to explicitly ensure that
> certain things happen in a particular order.
>
>
>
> This has been a thing for a while now, and it’s not even just because of
> the language, but also because of out of order execution in modern cpu
> design.
>
>
>
> *From:* Std-Discussion <std-discussion-bounces_at_[hidden]> *On
> Behalf Of *jim x via Std-Discussion
> *Sent:* Wednesday, June 10, 2026 11:47
> *To:* jim x via Std-Discussion <std-discussion_at_[hidden]>
> *Cc:* jim x <xmh970252187_at_[hidden]>
> *Subject:* [std-discussion] Does the C++ abstract machine recognize a
> temporal order of execution?
>
>
>
> Consider this example:
>
> ````cpp
> #include <atomic>
> #include <chrono>
> #include <thread>
>
> uint64_t timestamp() {
> auto now = std::chrono::steady_clock::now().time_since_epoch();
> return
> std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
> }
>
> int main() {
> std::atomic<long int> val = 0;
> long int now1, now2;
> auto t1 = std::thread([&]() {
> val.store(1,relaxed); // #1
> now1 = timestamp(); // #2
> });
> auto t2 = std::thread([&]() {
> now2 = timestamp(); // #3
> val.load( relaxed ); // #4
> });
> t1.join();
> t2.join();
> }
>
> ````
>
> This question arises from whether we can determine if a specific execution
> outcome is caused by inter-thread latency within the abstract machine. A
> possible execution of the above example is that #4 reads 0 even when now1
> < now2.
>
>
>
> Both intro.execution p8 <https://eel.is/c++draft/intro.execution#8>
>
> > Given any two evaluations A and B, if A is sequenced before B (or,
> equivalently, B is sequenced after A), *then the execution of A shall
> precede the execution of B*.
>
>
>
> and [stmt.pre] p1
>
> > Except as indicated, statements are executed in sequence
> ([intro.execution]).
>
>
>
> state that the control flow executes expressions in sequential order
> within a single thread, provided one evaluation is sequenced before another.
>
>
>
> Furthermore, *[time.clock.steady] p1* states:
>
> > Objects of class steady_clock represent clocks for which values of
> time_point never decrease as physical time advances and for which values of
> time_point advance at a steady rate relative to real time. That is, the
> clock may not be adjusted.
>
>
>
> and *[time.clock.req] p2* states:
>
> > C1::now(): Returns a time_point object representing the current point in
> time.
>
>
>
> This implies that calling now() samples a global time point when the
> control flow executes it. Since the control flow cannot reach #2 without
> first executing #1, #1 must be executed by the control flow at a point in
> time no later than the time point returned by #2. The same logic applies
> to #3 and #4.
>
>
>
> Therefore, when now1 < now2, does it imply that #1 is executed by the
> control flow of t1 at a point in time strictly earlier than when #4 is
> executed by the control flow of t2, from the perspective of the abstract
> machine? (Note that this does not refer to a happens-before relationship,
> but rather a temporal comparison of the control flows executing these
> expressions.)
>
>
>
> As a minor clarification, this is not a question about physical
> implementations (which are governed by the "as-if" rule), but rather a
> conceptual question about the formal behavior defined by the C++ abstract
> machine.
>
>
>
> The deduction above is based entirely on existing rules within the
> standard, and there seems to be no explicit rule that contradicts this
> interpretation. Consequently, this appears to be a gray area in the
> specification. If this reasoning is indeed flawed, where exactly does the
> flaw lie? Furthermore, are there any specific rules in the standard that
> would directly negate this conclusion?
>
>

Received on 2026-06-11 02:28:27