That doesn't change the fact that the standard still considers it undefined.

The premise of your claim that the program in my question is undefined is that it contains a data race, and whether a program contains a data race is determined by the rules in [intro.race] p17. One of the conditions in paragraph 17 is "at least one of which is not atomic"—if both operations are atomic, then no data race exists. Meanwhile, another rule in the standard states: "The semantics of an access through a volatile glvalue are implementation-defined", which means the semantics of the access depend on the specific implementation and serve as an open parameter within the abstract machine.

The question, then, is this: if an implementation defines these operations to be identical to std::atomic_ref::load() / store(), does the condition "at least one of which is not atomic" in [intro.race] p17 evaluate to false? In that case, is the program still undefined? This is the core issue, whereas your initial claim that the program is simply undefined completely skipped the process of determining whether a data race actually exists.


On Wed, Oct 14, 2026 at 6:02 PM Andrey Semashev via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
On 14 Oct 2026 05:41, jim x wrote:
> Doesn't such behavior depend on how the implementation defines its
> semantics? That is, *shouldn't it be considered implementation-defined,
> rather than unconditionally undefined?*

Which behavior? Data races cannot be implementation-defined because in
general the implementation cannot define a behavior without enforcing
it, as it isn't cost-free and the cost isn't justified.

Also, an implementation may define behavior where the standard leaves it
undefined. You were given an example of gcc and signed integer overflow
earlier. That doesn't change the fact that the standard still considers
it undefined.

> On Tue, Oct 13, 2026 at 8:43 PM Andrey Semashev via Std-Discussion <std-
> discussion@lists.isocpp.org <mailto:std-discussion@lists.isocpp.org>> wrote:
>
>     On 13 Oct 2026 15:18, Giuseppe D'Angelo via Std-Discussion wrote:
>     > Il 13/10/26 12:24, Andrey Semashev via Std-Discussion ha scritto:
>     >> You got it backwards. If the standard doesn't say volatile operations
>     >> are atomic then they are not. Or put it another way, you cannot
>     rely on
>     >> them being atomic. Atomicity is not implied, the standard must
>     >> explicitly require an operation to be atomic for an implementation to
>     >> make an effort in making them atomic in the compiled program.
>     >
>     > Devil's advocate here: can an implementation say that reading a
>     > `volatile int x` is defined as doing `atomic_ref<int>(x).load()`?
>     >
>     > (Same for the rest of operations.)
>
>     It can, and that would be an example of an implementation-defined
>     behavior.
>
>     > If yes, would that make concurrent access to volatile ints not subject
>     > to data races?
>
>     On that particular implementation, yes. According to the standard or on
>     other implementations that do not use atomic operations for
>     volatiles, no.
>
>     --
>     Std-Discussion mailing list
>     Std-Discussion@lists.isocpp.org <mailto:Std-Discussion@lists.isocpp.org>
>     https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>     <https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion>
>

--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion