C++ Logo

std-discussion

Advanced search

Re: What is an access in [res.on.objects]?

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Thu, 10 Nov 2022 20:12:48 +0000
On Thu, 10 Nov 2022 at 18:07, Andrey Erokhin via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> >>>>>>> According to a non-normative note in
> >>>>>> https://eel.is/c++draft/defns.access,
> >>>>>>>
> >>>>>>> "Only glvalues of scalar type can be used to access objects. ...
> >>>>>> Attempts to read or modify an object of class type typically invoke
> a
> >>>>>> constructor or assignment operator; such invocations do not
> themselves
> >>>>>> constitute accesses, although they may involve accesses of scalar
> >>>>>> subobjects."
> >>>>>>>
> >>>>>>> The question is, can objects of class type be accessed?
> >>>>>>
> >>>>>> Can, in some sense. But it would be UB. E.g.
> >>>>>>
> >>>>>> struct S
> >>>>>> {
> >>>>>> char buf[sizeof(int)];
> >>>>>> } s;
> >>>>>>
> >>>>>> reinterpret_cast<int&>(s) = 0; // kinda accesses `s`, but this
> >> violates
> >>>>>> strict aliasing, so the behavior is actually undefined
> >>>>>>
> >>>>>
> >>>>> It accesses `s`'s storage, sure.
> >>>>
> >>>> What do you mean by explicitly writing «storage»? You disagree with
> that
> >>>> the expression accesses `s`?
> >>>>
> >>>
> >>> Yes, since `s` is not a glvalue of scalar type.
> >>
> >> But reinterpret_cast<int&>(s) is. And it denotes the `s` object. Per
> >> [expr.ass]/2, the referred-to object is accessed.
> >>
> >
> > Why does it denote `s`?
>
> Hm. Because the standard says so.
>

In which section? Is this [expr.static.cast]/11?

> That looks to me like it ends the lifetime of `s`.
>
> With undefined behavior, everything is vacuously true.
>

Sorry, I was thinking of [intro.object], but that only works with `new`.

>>> But a read would not have undefined behavior.
> >>>>
> >>>> [basic.lval]/11 apply uniformly to both kinds of access: reads and
> >> writes.
> >>>>
> >>>
> >>> Oh oops, didn't spot that the reinterpret_cast was to int. If it was
> to a
> >>> storage-like type, that would be well-defined, no?
> >>
> >> No.
> >>
> >
> > Why would [basic.types.general] not hold?
>
> You mean [basic.types.general]/2? Don't think it would count as copying
> the object's underlying bytes to the array.
>

Again, my mistake; I was thinking of [basic.lval]/11.

And that resolves the whole discussion (well, via a Note):

> [...] C++ has no notion of accessing an object of class type through an
lvalue of class type.

Received on 2022-11-10 20:13:01