This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/19403] [4.0 Regression] name lookup is broken with friends


------- Additional Comments From lerdsuwa at gcc dot gnu dot org  2005-01-13 14:52 -------
> So B's ctor uses the global A without the friend declaration and with the 
> friend declaration the local injected A? Sometimes the holy standard confuses 
> me a bit.

No. With or without friend declaration, the B's ctor should always pick
the global A.  This is one weird rule in C++ standard.  
The idea is that name lookup for 'friend struct A;' only find A within 
one level outside the classes enclosing the friend declaration:

  namespace N {
    class A {
      class B {
        friend class C; // Classes A and B enclosing this friend.
                        // one level up is namespace N.
                        // Since there is no B::C nor A::C,
                        // this refers to N::C
      };
    };
  }

  void f() {
    class D {
      friend class E;   // Since there is no D::E, one level up
                        // is the local class E inside function f.
    };
  }

When refer to A without the prefix 'class' or 'struct', any name
can be used.  However the name introduced by friend must be
explicitly declared first to be visible.

Now it's your example, expanded with more cases and comment describing
the way it should be handled.

  struct A {}; 
 
  namespace Boo 
  { 
     struct B 
     { 
       friend struct A; // Since there is no B::A, this means Boo::A
                        // It introduces Boo::A but still invisible
                        // since there is no Boo::A declaration prior
                        // to this friend.
 
       B(const A&) {}; // Boo::A is still not visible,
                       // so ::A is chosen here
     };

     void f(const A&) {} // Boo::A is still not visible, choose ::A

     struct A; // Declare Boo::A explicitly, so Boo::A is now visible

     void g(const A&) {} // Choose Boo::A
  }

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19403


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]