Reputation: 1918
I have a class which has a friend function declared and defined inside the class and I'm calling this function from another function within the class. Clang compiler (3.3) complains for undeclared identifier for the friend function. I have compiled this code with MSVC and gcc and it works on both compilers but now with Clang port I'm getting this problem. Here's a simplified example case of the problem:
class foo
{
friend void bar() {}
void asd() {bar();}
};
In Clang I get: error : use of undeclared identifier 'bar'
. If I declare/define pla() outside the class, it works fine, but I have some macros which force me to define the function within the class. Is this some known issue in Clang or is Clang somehow more pedantic about the C++ name lookup while still conforming the C++ standard? Is there some known workaround for it while defining/declaring the function within the class?
Upvotes: 2
Views: 2181
Reputation: 137310
The relevant rule is found in §7.3.1.2 [namespace.memdef]/p3:
Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship). If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2).
In other words, when a friend
function is only defined inline inside a class and never declared outside it, the only way it can be found is through ADL, which does not apply here as bar()
takes no arguments. There must be a matching declaration of the function in the innermost enclosing namespace before it can be found by non-ADL name lookup.
Upvotes: 6
Reputation: 310940
According to the C++ Standard
7 Such a function is implicitly inline. 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 (3.4.1).
I understand words "lexical scope" such a way that its name is visible in the class scope. So taking this into account it seems that there is a bug in Clang.
Though I did not find the definition of the term "lexical scope". So this paragraph can be interpretated as that the friend function itself can access members of the class without their qualification or the way I said about above.
For example such code is compiled without problem
struct A
{
friend void f() { x = 20; }
static int x;
};
int A::x;
int main() {}
But this one is not compiled
struct A
{
friend void f();
static int x;
};
int A::x;
void f() { x = 20; }
int main() {}
Upvotes: 3