below code cannot be compiled: ----------- #define TYPE N::C #define ASSIGN do {} while(0) //#define ASSIGN do { x->i = 0;} while(0) //#define TYPE N::B namespace N { class B; class C; } void func(TYPE * x); namespace N { class B { int i; }; class C { int i; friend void func(TYPE * x); }; } void func(TYPE * x) { ASSIGN; } int main() { TYPE x; func(&x); return 0; } -----------
g++ report: ------------ /test-cpp.cpp: In function 'int main()': ./test-cpp.cpp:22: error: call of overloaded 'func(N::C*)' is ambiguous ./test-cpp.cpp:18: note: candidates are: void func(N::C*) ./test-cpp.cpp:15: note: void N::func(N::C*) ------------ change #define TYPE N::C to #define TYPE N::B then the code can be compiled. According to [namespace.memdef] and [basic.scope.pdecl]: --------------- friend declarations refer to functions or classes that are members of the nearest enclosing namespace, but they do not introduce new names into that namespace (7.3.1.2). --------------- According to standard, ::func(N::C * x) shouldn't become friend of N::C, but there should no ambiguous, because 'friend void func(TYPE * x);' look for N::func(N::C *), and it doesn't exist at all. According to [namespace.memdef], the names introduced by 'friend' is invisible until its real declaration. It seems that, g++ wrongly introduces a name: N::func(N::C*) into namespace N, and when calling func(N::C*), it follows koenig lookup and finds N::func(N::C*). In the situation of 'friend void N::func(N::B*)', g++ works correctly. -- Summary: g++: friend introduce name into class, violate standard Product: gcc Version: 4.3.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: pi3orama at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41960