--- class address { protected: static int parseNext(int a); }; class mailbox : public address { friend class mailboxField; }; class mailboxField { void parse(int a) { address::parseNext(a); // will work with: // mailbox::parseNext(a); } }; --- It should trigger: address.cpp: In member function ‘void mailboxField::parse(int)’: address.cpp:4:16: error: ‘static int address::parseNext(int)’ is protected address.cpp:17:33: error: within this context Tested with g++ 4.6.2
EDG and Solaris CC also accept it, clang doesn't The code looks similar to this example from [class.protected] in the standard: class B { protected: int i; static int j; }; class D1 : public B { }; class D2 : public B { friend void fr(B*,D1*,D2*); }; void fr(B* pb, D1* p1, D2* p2) { // ... p2->i = 3; // OK (access through a D2) p2->B::i = 4; // OK (access through a D2, even though // naming class is B) // ... B::j = 5; // OK (because refers to static member) D2::j = 6; // OK (because refers to static member) } Note that the friend of D2 can access non-static members of B through D2* and can access static members of B directly.
I think G++ is correct here. [class.protected]p1 An additional access check beyond those described earlier in Clause 11 is applied when a non-static data member or non-static member function is a protected member of its naming class (11.2)* * This additional check does not apply to other members, e.g., static data members or enumerator member constants. address::parseNext refers to the same entity as mailbox::parseNext and access to static members does not involve an object expression, so there is no need for that access to be done through an object expression of the derived type.
Clang gets this wrong on purpose: http://llvm.org/bugs/show_bug.cgi?id=6840 But G++ implements what the standard says, so INVALID
I found this bug (or behavior) while playing with clang. I am not really sure to understand why friend class should impact his parent but if g++ respects the standard, why not...
(In reply to comment #4) > I am not really sure to understand why friend class should impact his parent > but if g++ respects the standard, why not... It doesn't "impact his parent" Read comment 2 again. To access a protected non-static member you must do so though an object expression of the derived type, because in the expression 'p->address::m' you only know if 'm' is a member of a 'mailbox' object when 'p' has type 'mailbox*' But for a static member that is irrelevant, the static member just exists independently of any 'mailbox' or 'address' instance, so if mailboxField can access members of 'mailbox' then it can access the static member, and it doesn't matter if you refer to it as 'mailbox::parseNext' or 'address::parseNext' because both refer to the exact same entity.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.