c++multiple-inheritancename-hiding

Name hiding when multi-inherited


According to https://www.ibm.com/docs/en/i/7.5?topic=only-name-hiding, the assignment x = 0 in the following code is not ambiguous, because the declaration B::x has hidden A::x.

struct A {
   int x;
};

struct B: A {
   int x;
};

struct C: A, B {
   void f() { x = 0; }
};

int main() {
   C i;
   i.f();
}

Is this correct? It sounds counterintuitive to me, so I tried copying it to https://cpp.sh/ to compile it. It didn't compile successfully, due to ambiguity.


Solution

  • Your compiler is right. The article is wrong, supposed it actually describes standard c++ (see pps).

    What they say about name hiding applies for example here:

    struct A {
       int x;
    };
    
    struct B: A {
       int x;
       void f() { x = 0; }
    };
    

    If there were no int x; in B then x in f() would refer to A::x, but the member is hiding the member of same name from the base, hence x in f does refer to B::x. There is no ambiguity.

    This does however, not apply to multiple inheritance as in the example on the page:

    struct A {
       int x;
    };
    
    struct B: A {
       int x;
    };
    
    struct C: A, B {
       void f() { x = 0; }
    };
    

    It would actually be weird if the order of struct C: A,B vs struct C: B,A would determine the namelook up for x. Instead, unqualified name lookup for a member in a nutshell works like this:

    This is only a very simple view (just enough to understand the examples), for the details I refer you to https://en.cppreference.com/w/cpp/language/unqualified_lookup.


    PS: THe article has more misleading information.

    However, the compiler will warn you that deriving C from A is redundant because you already have access to the subobject A through B.

    "redundant" is the wrong word here. A C object has two distinct A subobjects. Its just not possible to access either of them, because whatever way you'd use to access it cannot differentiate between the A inherited via B and the one inherited directly.


    PPS: The reason for this discrepancy might be that you are looking at (quoted from here):

    These manuals provide guidance and reference material for the American National Standards Institute (ANSI) Standard C++ Library and the Integrated Language Environment (ILE) versions of the C and C++ programming languages.

    I never heard of a "ILE version of C++" before, though it appears to be a dialect.