C++ Logo

std-discussion

Advanced search

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

From: Jennifier Burnett <jenni_at_[hidden]>
Date: Fri, 09 Oct 2026 07:16:48 +0100
I'm not sure there's a conflict? Implementations are perfectly allowed to define undefined behaviour to have some specific behaviour. I'm allowed to create an implementation that has a defined behaviour for *all* data races, for example. The standard says that anything can happen when undefined behaviour occurs, and implementation-defined behaviour does fall under the category of "anything".

On 9 October 2026 06:11:15 BST, jim x via Std-Discussion <std-discussion_at_[hidden]> wrote:
>Consider this example:
>````cpp
>
>#include
>
>int main(){
> volatile int value = 0;
> std::jthread t1([&](){
> auto i = value; // #1
> });
> std::jthread t2([&](){
> value = 1; // #2
> });
>}
>
>````
>People think this program should contain a data race because `#1` and `#2`
>are *non-atomic* operations, which satisfies the condition in [intro.races]
>p17
><https://eel.is/c++draft/intro.races#17>
>
>Two actions are *potentially concurrent*
><https://eel.is/c++draft/intro.races#def:potentially_concurrent> if
>
> they are performed by different threads, or
>> <https://eel.is/c++draft/intro.races#17>
>
>The execution of a program contains a data race if it contains two
>> potentially concurrent conflicting actions, *at least one of which is not
>> atomic*, and neither happens before the other, except for the special
>> case for signal handlers described below. Any such data race results in
>> undefined behavior ([ub:intro.races.data]).
>
>
> However, this opinion is based on the premise that they consider the
>operations at `#1` and `#2` to be non-atomic operations in any way.
>However, [dcl.type.cv] p5 <https://eel.is/c++draft/dcl.type.cv#5>
>simultaneously states:
>
>*The semantics of an access through a volatile glvalue are
>implementation-defined.*
>
>
>How about if a hypothetical implementation specifies the semantics as
>follows:
>
>> An access to a volatile int glvalue value is defined to have the exact
>> semantics of std::atomic_ref<int>(value).load() for reads, and
>> std::atomic_ref<int>(value).store() for writes.
>
>
>Under these specified semantics, `#1` and `#2` should be considered as
>atomic operations, which won't satisfy the condition in [intro.race] p17,
>therefore no data race. From this perspective, isn't the program
>implementation-defined behavior? That is, whether the program contains a
>data race depends on how the implementation specifies the semantics

Received on 2026-10-09 06:17:01