Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CWG1699 Does befriending a class befriend its friends? #1573

Open
jensmaurer opened this issue May 31, 2023 · 3 comments
Open

CWG1699 Does befriending a class befriend its friends? #1573

jensmaurer opened this issue May 31, 2023 · 3 comments
Labels
EWG Evolution paper needed An issue needs a paper to describe its solution

Comments

@jensmaurer
Copy link
Member

A friend declaration is a member-declaration, but it is not clear how far the granting of friendship goes in a friend declaration. For example:

  class c {
    class n {};
    friend struct s;
  };

  struct s {
    friend class c::n;          // #1
    friend c::n g();            // #2
    friend void f() { c::n(); } // #3
  };

In particular, if a friend function is defined inside the class definition, as in #3, does its definition have access to the private and protected members of the befriending class? Implementations vary on this point.

See CWG1699 for the full discussion.

@jensmaurer jensmaurer added the EWG Evolution label May 31, 2023
@erichkeane
Copy link
Collaborator

EWG Discussed this on Monday in Varna, and the following poll was taken:

EWG agrees with the 'first' CWG proposed solution from the November '21 rationale on CWG 1699, that friend functions defined in a class get access to the private/protected members of the class, however friend functions NOT defined in the class definition do not.

SF F N A SA
2 14 5 1 1

However, further discussion lead to further explanation of the inconsistencies, and EWG determined that a paper (written by @jfbastien, Jeff Snyder, et al) explaining the following examples should be presented later in the week:

  class c {
    class n {};
    friend struct s;
  };

c::n g() { // #4 
  // 'n' accessible here? 
}
  struct s {
    friend class c::n;          // #1
    friend c::n g();            
	    friend c::n h();            
    friend void f() { c::n(); } // #3 (EDG/MSVC Reject, Clang/GCC Accept)
  };
  
c::n h() { // #5 
  // 'n' accessible here? 
}
3 disallowed
3 &4 allowed, same meaning (no matter where 4 is)
3 & 5 allowed, same meaning (5 only allowed if 'after' friendship)

Sad paper is encouraged to consider templates (class template, function template, and member function templates), as well as modules.

@t3nsor
Copy link

t3nsor commented Jun 12, 2023

Note that there's a similar issue that is usually considered to be part of CWG1699: if f is a friend of T, does f also have access to private members of the class that T is nested withn?

class A {
    static int x;
    class B {
        friend int f() { return A::x; }  // OK?
        friend int g();
    };
};

int g() { return A::x; }  // OK?

It would be good if the paper would also discuss this case.

@jfbastien
Copy link
Collaborator

The discussion included a request to discuss templates in modules as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
EWG Evolution paper needed An issue needs a paper to describe its solution
Projects
None yet
Development

No branches or pull requests

4 participants