From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1491 invoked by alias); 6 Nov 2009 03:51:20 -0000 Received: (qmail 1467 invoked by uid 48); 6 Nov 2009 03:51:10 -0000 Date: Fri, 06 Nov 2009 03:51:00 -0000 Subject: [Bug c++/41960] New: g++: friend introduce name into class, violate standard X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "pi3orama at gmail dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2009-11/txt/msg00484.txt.bz2 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