C++ Logo

std-proposals

Advanced search

Re: [std-proposals] The limits of friendship

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Tue, 6 May 2025 21:05:44 -0400
On Tue, May 6, 2025 at 8:05 PM Magnus Fromreide via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> Hello!
>
> I tried to declare two classes:
>
> class A {
> private:
> void f();
> void g();
> };
>
> class B {
> private:
> friend void A::f();
> void x();
> };
>
> and then got surprised when my compiler told me that I need to be able to
> call A::f in order to grant it friendship.

No, you need to be able to *name* a thing in order to grant it friendship.

If you have private access to a class, and you get a member pointer to
something private in that class, and you hand that member pointer to
code that should not have private access to the class... that code can
use that member pointer to access the "private" stuff.

Access controls are based on controlling who gets to use the *name* of
an entity, not who gets to use it. And since `B` is not a friend of
`A`, the definition of `B` cannot name any non-public member of `A`.

> I am perfectly happy with not beeing able to call or take the address of
> A::f but I think it should be possible to grant friendship to a private
> member.

Even ignoring the above, this makes no sense conceptually.

If something is private, then the outside world (aside from friends)
shouldn't know it *exists* (introspection aside). It's not merely
"hands off"; it's "you don't see this". This allows those who control
that class to change the privates of the class with at least some
reasonable assurance that such changes won't break code they haven't
explicitly given permission to (obviously things like introspection
limit this, but if you use introspection to break access controls,
you've taken responsibility for that yourself).

What you're asking for would prevent that.

Received on 2025-05-07 01:05:56