C++ Logo

std-discussion

Advanced search

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

From: jim x <xmh970252187_at_[hidden]>
Date: Thu, 15 Oct 2026 13:39:50 +0800
>
> I don't think that there's anywhere that an IB choice can make what is
> otherwise UB not so.


If the standard deems a program to have undefined behavior, then regardless
of how an implementation guarantees its specific behavior, the program is
undefined from the perspective of the standard—there is no dispute about
this. However, the crux of the problem is that ambiguity arises in the very
process of applying the standard's rules to determine whether the program
is undefined in the first place.

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 Thu, Oct 15, 2026 at 1:24 PM Thiago Macieira <thiago_at_[hidden]> wrote:

> On Wednesday, 14 October 2026 22:15:52 Pacific Daylight Time jim x wrote:
> > But my question isn't about implementation conformance; that is, I didn't
> > ask whether a conforming implementation can specify a concrete behavior
> for
> > the undefined behavior program; of course, it can. I'm asking what the
> > program's behavior should be, given the current wording, within the scope
> > the standard leaves to implementations to define the semantics of access.
>
> The problem here is what you're assuming can be implementation-defined.
> There
> are a few things the Standard requires implementations make a choice,
> document, and stick to it, which we call "implementation-defined
> behaviour". IB
> is never UB. I don't think that there's anywhere that an IB choice can
> make
> what is otherwise UB not so.
>
> And then there's UB, which an implementation can, if it wants to, make
> defined.
> It does not need to document it, but it can too. But making such choices
> does
> not change the Standard. From its point of view, it's still UB.
>
> > In other words, since the premise based on which we say the program is
> > undefined is that the program contains a data race as per [intro.race]
> p17,
> > which depends on whether the condition "at least one of which is not
> > atomic" is true, the current wording is unclear about whether the
> > operations at `#1` and `#2` are non-atomic even if the implementations
> > define the semantics as being equivalent to
> > `std::atomic_ref::load()/store()`.
>
> There is a data race from the Standard's point of view.
>
> If this implementation chose to implement the particular access in
> question
> atomically, then in this implementation there would be no data race. But
> it
> does not change the Standard: it's still UB from its point of view.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Principal Engineer - Intel Data Center - Platform & Sys. Eng.
>

Received on 2026-10-15 05:40:02