I understand that the following C++ code snippet should produce an error in the definition of g, because p.t.x is private and cannot be accessed there.
class P {
class T {
int x;
friend class P;
};
T t;
friend void g(P &p);
};
void g(P &p) { p.t.x = 42; }
What puzzles me is the next snippet. It differs only in the fact that the definition of the friend function g now occurs inside class P.
class P {
class T {
int x;
friend class P;
};
T t;
friend void g(P &p) { p.t.x = 42; }
};
Clang++ (both 6.0.0-1ubuntu2 and Apple version clang-1100.0.33.8) compiles the latter with no error, whereas GNU C++ (7.5.0-3ubuntu1~18.04) produces the same error as in the former snippet.
I understand that the function g defined in the latter case is not in the same scope
as the one defined in the former (cf. a related question and an older longer discussion) and it's only visible through ADL. But I think what I'm asking here is different: should the declaration friend class P in class T extend to the body of friend function g or not?
The relevant part of the C++ standard (§11.3 or §11.9.3 in more recent drafts) states that:
7 ... A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (6.5.1).
So I understand that Clang++ and GNU C++ interpret differently what is meant by "lexical scope" (see also this answer to the previous related question). Clang++ seems to compile g as if it were a friend of class T, probably because it's in the lexical scope of class P which is a friend of class T, whereas GNU C++ does not.
- Is there a bug in one of the two compilers?
- If yes, which one?
- Regardless of the answers to the previous questions, isn't this something that the standard should formalise better?