[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