Date: Thu, 27 Feb 2025 10:09:32 -0500
On Wed, Feb 26, 2025 at 7:19 PM Russell Shaw via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> On 27/2/25 00:36, Andrew Schepler wrote:
> > On Wed, Feb 26, 2025 at 8:07 AM Russell Shaw via Std-Discussion <std-
> > discussion_at_[hidden] <mailto:std-discussion_at_[hidden]>>
> wrote:
> >
> > Hi,
> >
> > In [class.member.lookup], using g++, i get "error: request for
> member ‘x’ is
> > ambiguous" for 'f.x = 0;'
> >
> >
> > clang++ 19.1.0, icpx 2025.0.0, and MSVC 19 all compile it without errors
> or
> > warning, matching the Standard's requirements. A gcc bug report is
> already open:
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77725 <https://gcc.gnu.org/
> > bugzilla/show_bug.cgi?id=77725>
>
> Hi,
>
> I don't like that the std says it's non-ambiguous.
>
> It's clearly ambiguous. How does it justify that it's not ?
>
The reason why it's not ambiguous is that the E subobject contains all A
and B subobjects of an F object.
If you want a stricter rule, e.g. that lookup finds E::x unambiguously only
if every path to an x passes through E, then you should try prototyping it
in a compiler and seeing how much code it breaks.
I expect you'll find that, in this particular case, it's easier to realign
your expectations with the standard than it is to change the standard.
>
> The wording 'is unambiguous because the A and B base class subobjects'
> seems to
> first appear in 2017/n4640.txt
>
> Did clang++/icpx/MSVC change their lookup algorithm from prior to 2017 ?
>
> > ------------------------------------------------------
> > example 1
> >
> > struct A { int x; }; // S(x,A) = { { A::x }, { A } }
> > struct B { float x; }; // S(x,B) = { { B::x }, { B } }
> > struct C: public A, public B { }; // S(x,C) = { invalid, { A in
> C, B in C } }
> > struct D: public virtual C { }; // S(x,D) = S(x,C)
> > struct E: public virtual C { char x; }; // S(x,E) = { { E::x },
> { E } }
> > struct F: public D, public E { }; // S(x,F) = S(x,E)
> >
> > int main() {
> > F f;
> > f.x = 0; // OK, lookup finds
> E::x
> > }
> > ------------------------------------------------------
> >
> > I agree with g++ because the inheritance diagram is:
> >
> > A.x B.x
> > \ /
> > C
> > / \
> > D E.x
> > \ /
> > F
> >
> > f.x could be A.x, B.x, or E.x, but the standard is saying that it's
> unambiguous.
> > --
> > Std-Discussion mailing list
> > Std-Discussion_at_[hidden] <mailto:
> Std-Discussion_at_[hidden]>
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
> <https://
> > lists.isocpp.org/mailman/listinfo.cgi/std-discussion>
> >
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
std-discussion_at_[hidden]> wrote:
> On 27/2/25 00:36, Andrew Schepler wrote:
> > On Wed, Feb 26, 2025 at 8:07 AM Russell Shaw via Std-Discussion <std-
> > discussion_at_[hidden] <mailto:std-discussion_at_[hidden]>>
> wrote:
> >
> > Hi,
> >
> > In [class.member.lookup], using g++, i get "error: request for
> member ‘x’ is
> > ambiguous" for 'f.x = 0;'
> >
> >
> > clang++ 19.1.0, icpx 2025.0.0, and MSVC 19 all compile it without errors
> or
> > warning, matching the Standard's requirements. A gcc bug report is
> already open:
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77725 <https://gcc.gnu.org/
> > bugzilla/show_bug.cgi?id=77725>
>
> Hi,
>
> I don't like that the std says it's non-ambiguous.
>
> It's clearly ambiguous. How does it justify that it's not ?
>
The reason why it's not ambiguous is that the E subobject contains all A
and B subobjects of an F object.
If you want a stricter rule, e.g. that lookup finds E::x unambiguously only
if every path to an x passes through E, then you should try prototyping it
in a compiler and seeing how much code it breaks.
I expect you'll find that, in this particular case, it's easier to realign
your expectations with the standard than it is to change the standard.
>
> The wording 'is unambiguous because the A and B base class subobjects'
> seems to
> first appear in 2017/n4640.txt
>
> Did clang++/icpx/MSVC change their lookup algorithm from prior to 2017 ?
>
> > ------------------------------------------------------
> > example 1
> >
> > struct A { int x; }; // S(x,A) = { { A::x }, { A } }
> > struct B { float x; }; // S(x,B) = { { B::x }, { B } }
> > struct C: public A, public B { }; // S(x,C) = { invalid, { A in
> C, B in C } }
> > struct D: public virtual C { }; // S(x,D) = S(x,C)
> > struct E: public virtual C { char x; }; // S(x,E) = { { E::x },
> { E } }
> > struct F: public D, public E { }; // S(x,F) = S(x,E)
> >
> > int main() {
> > F f;
> > f.x = 0; // OK, lookup finds
> E::x
> > }
> > ------------------------------------------------------
> >
> > I agree with g++ because the inheritance diagram is:
> >
> > A.x B.x
> > \ /
> > C
> > / \
> > D E.x
> > \ /
> > F
> >
> > f.x could be A.x, B.x, or E.x, but the standard is saying that it's
> unambiguous.
> > --
> > Std-Discussion mailing list
> > Std-Discussion_at_[hidden] <mailto:
> Std-Discussion_at_[hidden]>
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
> <https://
> > lists.isocpp.org/mailman/listinfo.cgi/std-discussion>
> >
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
-- *Brian Bi*
Received on 2025-02-27 15:09:47