1

Different compiler seems to have different opinion on the subject. The following code compiles fine with gcc, but fails with clang:

class Base {
protected:
    static void f() {}
};

class Derived : public Base {
    friend class DerivedFriend;
};

class DerivedFriend {
public:
    void g() {
        Base::f();
    }
};

clang's error is:

main.cpp:13:15: error: 'f' is a protected member of 'Base'
        Base::f();
              ^
main.cpp:3:17: note: declared protected here
    static void f() {}
                ^
1 error generated.
anxieux
  • 757
  • 5
  • 14
  • 1
    possible duplicate? http://stackoverflow.com/questions/491000/friend-class-inherited-classes-are-not-friend-as-well – Blake McConnell Jun 03 '15 at 17:04
  • 1
    @BlakeMcConnell I don't think so. In the question you are pointing to, "friend arrow" has a different direction: class hierarchy is a friend of a single class. – anxieux Jun 03 '15 at 17:08
  • agreed, but have a look at this one: http://stackoverflow.com/questions/9878723/does-a-friend-see-base-classes – Blake McConnell Jun 03 '15 at 17:13
  • @BlakeMcConnell yes, this looks similar, but we wouldn't see T.C.'s exhaustive answer if I'd find this question before posting mine :) – anxieux Jun 03 '15 at 17:17
  • @BlakeMcConnell That one's for non-static members, for which there is an extra rule. – T.C. Jun 03 '15 at 17:19

1 Answers1

2

This is CWG issue 1873, which changed the rules for this case ([class.access.base]/p5):

A member m is accessible at the point R when named in class N if

  • [...]
  • m as a member of N is protected, and R occurs in a member or friend of class N, or in a member or friend of a class P derived from N, where m as a member of P is public, private, or protected, or
  • [...]

Here, N is Base, P is Derived, m is f(), and R occurs in a member of DerivedFriend; pre-CWG1873 this would be allowed, but CWG1873 removed the "friend of a derived class" case and makes this ill-formed.

The fix is to refer to f as a member of Derived rather than Base.

T.C.
  • 133,968
  • 17
  • 288
  • 421