Date: Tue, 9 Nov 2021 22:15:07 +0800
On Tue, 9 Nov 2021 at 00:11, <language.lawyer_at_[hidden]> wrote:
> On 08/11/2021 15:32, Yongwei Wu wrote:
> > On Mon, 8 Nov 2021 at 17:39, <language.lawyer_at_[hidden]> wrote:
> >
> >>> Maybe the intention is the same, but it is simply not clear from the
> text
> >>> that base-class access is defined and unrelated-class access is
> >> undefined.
> >>> It is clearer in C++17 [basic.lval]/6.10.
> >>
> >> [basic.lval] is not related to the incoherent object expression issue.
> >> And there is nothing special in base vs. non-base class from [expr.ref]
> >> POV.
> >>
> >> struct B1 { int i1; };
> >> struct B2 { int i2; };
> >>
> >> struct D : B1, B2 {};
> >>
> >> D d;
> >> B2* b2 = reinterpret_cast<B2*>(&d);
> >>
> >> After all, you don't read C++17 [basic.lval] as meaning that doing
> b2->i2
> >> is OK and (should) have defined behavior because it is «base-class
> access»?
> >>
> >
> > You do have a point, but this is not how I interpret the C++17 rule.
> >
> > According to the C++17 rule, if we have:
> >
> > struct B1 { int i1; };
> > struct B2 { int i2; };
> > struct B3 { int i3; };
> >
> > struct D : B1, B2 {};
> >
> > D* pD = …;
> > B2* pB2 = …;
> > B3* pB3 = …;
> >
> > Assuming the compiler cannot determine whether pD and pB2 are related
> (say,
> > they are passed in to a function), then changes to *pB2 should cause the
> > compiler to consider *pD is possibly changed. But whatever change made to
> > *pB3 will not cause the compiler to consider *pD might be tampered with.
> >
> > Does it still hold for C++20? If so, through which rules?
>
> I don't understand what is your concern here.
> Is it again a question about why, if pB3 is used with the -> operator,
> then it can be assumed to point to an object of type «cv B3»?
>
My understanding of the C++17 rule:
Writing to *pB2 may change *pD, and the compiler will always assume *pD
might have changed after I write to *pB2.
Whereas:
Writing to *pB3 must not change *pD (which would be undefined behaviour),
and the compiler will always assume *pD does not change after I write to
*pB3.
My question has two parts:
1) Does it still hold for C++20? (I would guess yes.)
2) If so, through which rules? (I cannot deduce the result from the C++20
standard text.)
> On 08/11/2021 15:32, Yongwei Wu wrote:
> > On Mon, 8 Nov 2021 at 17:39, <language.lawyer_at_[hidden]> wrote:
> >
> >>> Maybe the intention is the same, but it is simply not clear from the
> text
> >>> that base-class access is defined and unrelated-class access is
> >> undefined.
> >>> It is clearer in C++17 [basic.lval]/6.10.
> >>
> >> [basic.lval] is not related to the incoherent object expression issue.
> >> And there is nothing special in base vs. non-base class from [expr.ref]
> >> POV.
> >>
> >> struct B1 { int i1; };
> >> struct B2 { int i2; };
> >>
> >> struct D : B1, B2 {};
> >>
> >> D d;
> >> B2* b2 = reinterpret_cast<B2*>(&d);
> >>
> >> After all, you don't read C++17 [basic.lval] as meaning that doing
> b2->i2
> >> is OK and (should) have defined behavior because it is «base-class
> access»?
> >>
> >
> > You do have a point, but this is not how I interpret the C++17 rule.
> >
> > According to the C++17 rule, if we have:
> >
> > struct B1 { int i1; };
> > struct B2 { int i2; };
> > struct B3 { int i3; };
> >
> > struct D : B1, B2 {};
> >
> > D* pD = …;
> > B2* pB2 = …;
> > B3* pB3 = …;
> >
> > Assuming the compiler cannot determine whether pD and pB2 are related
> (say,
> > they are passed in to a function), then changes to *pB2 should cause the
> > compiler to consider *pD is possibly changed. But whatever change made to
> > *pB3 will not cause the compiler to consider *pD might be tampered with.
> >
> > Does it still hold for C++20? If so, through which rules?
>
> I don't understand what is your concern here.
> Is it again a question about why, if pB3 is used with the -> operator,
> then it can be assumed to point to an object of type «cv B3»?
>
My understanding of the C++17 rule:
Writing to *pB2 may change *pD, and the compiler will always assume *pD
might have changed after I write to *pB2.
Whereas:
Writing to *pB3 must not change *pD (which would be undefined behaviour),
and the compiler will always assume *pD does not change after I write to
*pB3.
My question has two parts:
1) Does it still hold for C++20? (I would guess yes.)
2) If so, through which rules? (I cannot deduce the result from the C++20
standard text.)
Received on 2021-11-09 08:15:11