JarkkoL
JarkkoL

Reputation: 1918

Clang: a friend function defined within a class

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

Answers (2)

T.C.
T.C.

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

Vlad from Moscow
Vlad from Moscow

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

Related Questions