On Wed, Feb 26, 2025 at 7:19 PM Russell Shaw via Std-Discussion <std-discussion@lists.isocpp.org> 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@lists.isocpp.org <mailto:std-discussion@lists.isocpp.org>> 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@lists.isocpp.org <mailto:Std-Discussion@lists.isocpp.org>
>     https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion <https://
>     lists.isocpp.org/mailman/listinfo.cgi/std-discussion>
>

--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion


--
Brian Bi