This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


471. Conflicting inherited access specifications

Section: 11.8.3  [class.access.base]     Status: NAD     Submitter: Mike Miller     Date: 14 Jun 2004

The Standard does not appear to specify how to handle cases in which conflicting access specifications for a member are inherited from different base classes. For example,

    struct A {
    public:
      int i;
    };
    struct B : virtual public A {
    protected:
      using A::i;
    };
    struct C : virtual public A, public B {
      // "i" is protected from B, public from A
    };

This question affects both the existing wording of 11.8.3 [class.access.base] paragraph 4 (“m as a member of N is public ... m as a member of N is private ... m as a member of N is protected”) and the proposed wording for issue 385 (“when a nonstatic data member or nonstatic member function is a protected member of its naming class”).

One possible definition of “is public” would be something like, “if any visible declaration of the entity has public access.” One could also plausibly define the access of m in N to be the minimum of all the visible declarations, or even an error if the visible declarations are inconsistent.

11.8.3 [class.access.base] paragraph 1 describes the access of inherited members, so a clarifying statement resolving this issue might plausibly be inserted at the end of that paragraph.

Proposed resolution (October, 2004):

Add the following text as a new paragraph after 11.8.3 [class.access.base] paragraph 1:

If a given base class can be reached along more than one path through a derived class's sub-object lattice (11.7.2 [class.mi]), a member of that base class could have different accessibility in the derived class along different paths. In such cases, the most permissive access prevails. [Example:

    struct B { static int i; };
    class I: protected B { };
    class D1: public B, public I { };
    class D2: public I, private B { };

i is accessible as a public member of D1 and as a protected member of D2. —end example]

Rationale (03/2005): This question is already covered, in almost identical words, in 11.8.7 [class.paths].