[cfe-dev] [PATCH] Friend class cannot access protected field of parent

John McCall rjmccall at apple.com
Mon Jun 7 23:33:42 PDT 2010


On Jun 7, 2010, at 8:36 AM, Olivier Goffart wrote:
> So I spend my week end, trying to get into the clang code. I chosen to try to 
> fix Bug 6840 [1] which is one of the last issue preventing Qt to compile.
> 
> 
> So the problem is with code like this:
> 
> class N { protected: static int m; };
> class P : public N { friend class R; };
> class R { int foo() { return N::n; } };
> 
> The C++ specification says that [class.access.base]
> 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 [...] friend of a class P
> derived from N, where m as a member of P is public, private, or protected
> 
> So this code should compile, because in R::foo() we can access N::m though P's 
> friendship.

Actually, I intentionally haven't implemented this rule yet.  It is either a
drafting error or a horrible mistake.  It neuters the entire 'protected'
specifier, it makes the well-formedness of code dependent on the
existence of completely unrelated classes, it imposes high costs on the
implementation, and it's formally undecidable in the presence of templates.
To wit:

  // Assume this has lots of specializations
  template <class> class Predicate;

  class A { protected: typedef int foo; };
  template <class T, bool = Predicate<T>::value> class B {};
  template <class T> class B<T, true> : public A { friend class C; };

  class C { A::foo x };

This reference is well-formed if and only if there exists a class T for which
Predicate<T>::value is true.

For a somewhat less abstract example, consider instead:
  template <class> class D;
  template <class T> class E : public D<T> { friend class C; };
Now 'C' is ill-formed unless there's a specialization of D which derives from A.

John.



More information about the cfe-dev mailing list