C++ Logo

std-discussion

Advanced search

Re: Implications of [res.on.data.races]

From: Ville Voutilainen <ville.voutilainen_at_[hidden]>
Date: Thu, 12 Jun 2025 20:33:36 +0300
On Thu, 12 Jun 2025 at 20:23, Ville Voutilainen
<ville.voutilainen_at_[hidden]> wrote:
>
> On Thu, 12 Jun 2025 at 18:06, Marvin Williams
> <marvinwilliams95_at_[hidden]> wrote:
> >
> > On Thu, 2025-06-12 at 13:01 +0300, Ville Voutilainen wrote:
> > > On Thu, 12 Jun 2025 at 11:56, Marvin Williams via Std-Discussion
> > > <std-discussion_at_[hidden]> wrote:
> > >
> > > > With the above interpretation, I can see how const may imply
> > > > bitwise
> > > > const, but I fail to see how Herb derives the internal
> > > > synchronization
> > > > requirement. In my understanding, the example given at 26:00,
> > > > locking a
> > > > mutable std::mutex member still modifies the object, violating
> > > > [res.on.data.races], if a standard library function were to call
> > > > w.get_info() on a const widget& w.
> > >
> > > Locking a mutable std::mutex member doesn't count as modifying the
> > > object. Because it doesn't modify
> > > the *observable* parts of the object, it just synchronizes access to
> > > them, making those accesses race-free.
> >
> > Is there something in the standard clarifying what exactly qualifies as
> > modification in this sense?
> > For example, would changing a private (non-atomic) int member still not
> > qualify as modifying? While it does not change the observable parts of
> > the object, it is certainly not thread-safe.
>
> Circling back to the beginning: the wording has changed since I last
> looked at it, but the current
> wording doesn't seem to leave any freedom to modify anything
> observable, no matter how synchronized.
> I don't see how this wording would allow modifications that are
> internally synchronized, it seems to ban
> modifications outright.
>
> I vaguely recall a proposal or an issue that changed that, but can't
> seem to find it based on that vague recollection.

But that recollection is wrong, because the wording hasn't changed for
~8 years or longer.

The relevant bit is thus "objects accessible by threads other than the
current thread". The library
can modify internal objects, and e.g. return copies of those. It can't
modify anything another thread
may have grabbed a reference or a pointer to. And *then*, we have two
plausible options how to implement
that, and those are either

A) seriously just don't modify anything
B) modify only things that aren't accessible, and make sure that
doesn't cause data races; not because there is specific
wording that says operations on const arguments aren't allowed to
cause data races, but because such operations
are as-if they don't modify anything. Because modifying nothing causes
no data races. Anything that modifies something
internal must have the same semantics, and therefore must be
race-free, via internal synchronization if need be.

Received on 2025-06-12 17:33:50