C++ Logo

std-discussion

Advanced search

Re: Is this program undefined-behavior or implementation-defined behavior?

From: Andrey Semashev <andrey.semashev_at_[hidden]>
Date: Sat, 10 Oct 2026 05:36:02 +0300
On 10 Oct 2026 04:44, jim x via Std-Discussion wrote:
> In your code, your objects are /not/ atomic. You do not have atomic
> accesses. Your (hypothetical or real) implementation says that
> volatile accesses have the same semantics as atomic accesses - that
> does not make them "atomic" in accordance with the C++ standard. C+
> + atomic accesses are accesses using the classes and functions from
> <atomic>.
>
> I have to say the standard didn't clearly define what "atomic" means,
> which is LWG2506 <https://cplusplus.github.io/LWG/issue2506>.
> Furthermore, even though we make the consensus that the operations
> defined in <atomic> are atomic operations, my question is: since the
> specific semantics for access through volatile glvalue are equivalent to
> `|std::atomic_ref<int>(value).load()|` for read and `|
> std::atomic_ref<int>(value).store(1)|` for write,

But they are not. AFAIR, the standard prohibits certain optimizations
and "out of thin air" operations on volatiles, but beyond that it
doesn't impose any requirements on how the operations on them are
carried out. In particular, it doesn't require loads and stores to be
atomic and visible in any particular order between threads.

> and both ` |
> std::atomic_ref<int>|::load` and ` |std::atomic_ref<int>|::store` are
> atomic operations defined <atomic>, why are `#1` and `#2`, under these
> specified semantics, not considered atomic operations? This is my confusion.

As was explained by other commenters, you're making a reverse
assumption. An implementation is allowed to implement volatiles using
atomic operations, and under that implementation the program you posted
would behave as expected. However, in terms of the C++ standard, that
program would still exhibit UB, because the standard only defines
behavior in terms of the abstract machine and not any specific
implementation. A different implementation could implement volatiles
differently, which would break your program. If a program may work or
break on different (conforming) implementations, this is UB by definition.

Received on 2026-10-10 02:36:14