Topic: Namespace questions


Author: wmm@fastdial.net
Date: Mon, 30 Oct 2000 21:14:10 GMT
Raw View
In article <1ej2wlj.iaij5e1n3osowN%joerg.barfurth@attglobal.net>,
  joerg.barfurth@attglobal.net (Joerg Barfurth) wrote:
> > And what happens in the following case?
> >=20
> > namespace // unnamed
> > {
> >   void f();
> > }
> >=20
> > class X
> > {
> >   friend void f(); // (unnamed)::f() or new function?
> > };
>
> I think this declares (unnamed)::f() as friend. A prior declaration is
> searched using unqualified name lookup. According to 3.4.1/2:
>
> "The declarations frrom the namespace nominated by a /using-directive/
> become visible in a namespace enclosing the /using-directive/; see
> 7.3.4. For the purpose of the unqualified name lookup rules described
in
> 3.4.1, the declarations from the namespace nominated by the
> /using-directive/ are considered members of that enclosing namespace."
>
> And again the unnamed namespace behaves as if there was a implicit
> using-directive.
>
> (A note in 3.4.1/7 indicates that 3.4.1 indeed applies "[...] when
> looking for a prior declaration for a class or function introduced by
a
> friend declaration [...]")

This is related to a spirited debate within the committee regarding
a number of questions on how friend declarations are handled.  See
http://www.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#138 and
the issues listed as related.

Current thinking (not mine personally, but I was in the minority)
is that friend lookup is very different from normal unqualified
lookup, in spite of the note you quoted, and consequently this
fragment will declare a new function ::f rather than making a
friend of the function that is a member of the unnamed namespace.

As I said, this is still under active discussion and might change
before it is finalized.

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: Mon, 30 Oct 2000 19:11:19 GMT
Raw View
"Christopher Eltschka" <celtschk@physik.tu-muenchen.de> wrote...
> I have a few questions according to namespace:
>
> Is the following code allowed?
>
> namespace A
> {
>   int i;
>   namespace B
>   {

Didn't you forget

        using namespace A;

here?

>   }
> }
>
> int main()
> {
>   A::B::i = 1; // access to A::i (visible from B), or illegal?

A::B doesn't have i declared.  The only 'i' here is A::i.
Unless, of course, B has 'using namespace A'...  Then I
don't know.  Probably OK.

> }
>
> What about the following?
>
> namespace // unnamed
> {
>   int i;
> }
>
> int main()
> {
>   int i = 3;
>   ::i = i; // access to (unnamed)::i, or to non-existant global i?

::i means that the i is from the global namespace.  The
global namespace here contains the name i from the unnamed
namespace because all members of the unnamed namespace are
brought to the global scope by the implicit using directive.
So, the '::i' and 'i' refer to the same object, I think.

> }
>
> And what happens in the following case?
>
> namespace // unnamed
> {
>   void f();
> }
>
> class X
> {
>   friend void f(); // (unnamed)::f() or new function?

The (unnamed)::f() is the only one available at this point.
So, I say, the former.

> };
>

Victor
--
Please remove capital A's from my address when replying by mail



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: Wed, 25 Oct 2000 00:40:55 GMT
Raw View
I have a few questions according to namespace:

Is the following code allowed?

namespace A
{
  int i;
  namespace B
  {
  }
}

int main()
{
  A::B::i = 1; // access to A::i (visible from B), or illegal?
}

What about the following?

namespace // unnamed
{
  int i;
}

int main()
{
  int i = 3;
  ::i = i; // access to (unnamed)::i, or to non-existant global i?
}

And what happens in the following case?

namespace // unnamed
{
  void f();
}

class X
{
  friend void f(); // (unnamed)::f() or new function?
};

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: tvinson@mpsisys.com
Date: 2000/10/25
Raw View
In article <39F448B3.475A8E74@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> I have a few questions according to namespace:
>
> Is the following code allowed?
>
> namespace A
> {
>   int i;
>   namespace B
>   {
        void f() { i = 1; }    // this isn't legal
        void g() { A::i = 0; } // need to qualify the variable
>   }
> }
>
> int main()
> {
>   A::B::i = 1; // access to A::i (visible from B), or illegal?
> }
No, You need to specify namespace A directly or through a using
directive in B (add "using namespace A" to namespace B).
You can't directly reference A::i within B either, see the added code.
>
> What about the following?
>
> namespace // unnamed
> {
>   int i;
> }
>
> int main()
> {
>   int i = 3;
>   ::i = i; // access to (unnamed)::i, or to non-existant global i?
> }
>
The leading :: notation always refers to the global namespace.  I don't
know of a way to reference a variable in an unnamed namespace if it is
shadowed by a local variable.
> ---


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: joerg.barfurth@attglobal.net (Joerg Barfurth)
Date: Thu, 26 Oct 2000 14:36:44 GMT
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:

> I have a few questions according to namespace:
>=20
> Is the following code allowed?
>=20
> namespace A
> {
>   int i;
>   namespace B
>   {
>   }
> }
>=20
> int main()
> {
>   A::B::i =3D 1; // access to A::i (visible from B), or illegal?
> }

No it is not allowed. See 3.4.3.2/2:=20

Qualified name lookup considers only declarations in the nominated
namespace (and in the transitive closure of used (via using-directives)
namespaces.)=20

There is no declaration of the name 'i' in namespace 'A::B' (and there
are no using-directives).
=20
> What about the following?
>=20
> namespace // unnamed
> {
>   int i;
> }
>=20
> int main()
> {
>   int i =3D 3;
>   ::i =3D i; // access to (unnamed)::i, or to non-existant global i?
> }

Legal. Access to (unnamed)::i. See 3.4.3/4 and 7.3.1.1.=20

The behavior of the unnamed namespace is as though you have

 namespace __some_unique_name {}
 using namespace __some_unique_name;
 namespace __some_unique_name { int i; }

and ::i refers to the 'i's defined in global scope or a namespace
nominated by a using directive in global scope (such as this unnamed
namespace).

> And what happens in the following case?
>=20
> namespace // unnamed
> {
>   void f();
> }
>=20
> class X
> {
>   friend void f(); // (unnamed)::f() or new function?
> };

I think this declares (unnamed)::f() as friend. A prior declaration is
searched using unqualified name lookup. According to 3.4.1/2:

"The declarations frrom the namespace nominated by a /using-directive/
become visible in a namespace enclosing the /using-directive/; see
7.3.4. For the purpose of the unqualified name lookup rules described in
3.4.1, the declarations from the namespace nominated by the
/using-directive/ are considered members of that enclosing namespace."

And again the unnamed namespace behaves as if there was a implicit
using-directive.

(A note in 3.4.1/7 indicates that 3.4.1 indeed applies "[...] when
looking for a prior declaration for a class or function introduced by a
friend declaration [...]")


HTH, J=F6rg

--=20
J=F6rg Barfurth                         joerg.barfurth@attglobal.net
-------------- using std::disclaimer; -----------------------------
Download:     StarOffice 5.2 at       http://www.sun.com/staroffice
Participate:  OpenOffice now at       http://www.OpenOffice.org

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: Thu, 26 Oct 2000 17:49:50 GMT
Raw View
Joerg Barfurth wrote:

[...]

Thank you very much for the explanation. After reading it and looking
up the cited sections in CD2 (they seem not to have changed
substantially - your explanation fits with them), it seems now
clear to me how the lookups work.

The third example turns out to get to something interesting:
If I understand correctly, the function is only considered
if the namespace inserted with the using directive is a
(direct or indirect) member of the class namespace:

namespace A
{
  void f();
}

namespace B
{
  namespace C
  {
    void g();
  }

  using namespace A;
  using namespace C;

  class X
  {
    friend void f(); // declares a new function void B::f()
    friend void g(); // refers to void B::C::g()
  };
}

This is due to the following facts (from CD2 - if that changed
in the final standard, please tell me):

- The name made visible with the using directive appears in the
  innermost namespace that (directly or indirectly) contains both
  (CD2 7.3.4 [namespace.udir]/2)
- friend functions are not looked up in the enclosing namespace
  (the [CD2 version of the] note you partially cited, and
  CD2 7.3.1.2 [namespace.memdef] referenced from there)

Therefore, A::f() appears to be in the global namespace, as seen
from class X, and therefore is not found during "friend lookup".
OTOH, B::C::g() appears to be in namespace A, as seen from class X,
and therefore is found during "friend lookup".
Somehow I doubt that is what was intended - IMHO either all
namespaces added with using directives should be considered,
or none.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: Thu, 26 Oct 2000 17:49:54 GMT
Raw View
tvinson@mpsisys.com wrote:
>
> In article <39F448B3.475A8E74@physik.tu-muenchen.de>,
>   Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> > I have a few questions according to namespace:
> >
> > Is the following code allowed?
> >
> > namespace A
> > {
> >   int i;
> >   namespace B
> >   {
>         void f() { i = 1; }    // this isn't legal

Really? I'd be quite surprised. Usually, containing scopes
are searched for if there's no shadowing declaration in the
inner scope.
In addition, in CD2, 3.4.1 [basic.lookup.unqual]/6 you find:

  A  name  used  in  the  definition of a function3) that is a member of
  namespace N [...] shall be declared before [...] or,
  if N is a nested namespace, shall be declared before its use in one of
  N's enclosing namespaces.  [Example:
          namespace A {
                  namespace N {
                          void f();
                  }
          }
          void A::N::f() {
                  i = 5;
                  // The following scopes are searched for a declaration
of i:
                  // 1) outermost block scope of A::N::f, before the use
of i
                  // 2) scope of namespace N
                  // 3) scope of namespace A
                  // 4) global scope, before the definition of A::N::f
          }
   --end example]

Note point 3 in the example (which is almost exactly the same
example as your extension of my code)!
I really doubt that this has changed in the final standard.

>         void g() { A::i = 0; } // need to qualify the variable
> >   }
> > }
> >
> > int main()
> > {
> >   A::B::i = 1; // access to A::i (visible from B), or illegal?
> > }
> No, You need to specify namespace A directly or through a using
> directive in B (add "using namespace A" to namespace B).

Yes, Joerg Barfurth pointed me to the correct position of the
standard (which seems not to have changed since CD2). Indeed,
the lookup does _not_ extend to enclosing namespaces here.

> You can't directly reference A::i within B either, see the added code.

This I doubt, see the added comment and CD2 quote.

[...]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: joerg.barfurth@attglobal.net (Joerg Barfurth)
Date: Thu, 26 Oct 2000 22:45:45 GMT
Raw View
<tvinson@mpsisys.com> wrote:

> > namespace A
> > {
> >   int i;
> >   namespace B
> >   {
>         void f() { i =3D 1; }    // this isn't legal
> >   }
> > }

> You can't directly reference A::i within B either, see the added code.

Of course you can. _Unqualified_ name lookup proceeds through enclosing
namespaces until the name is found. See 3.4.1.

Regards, J=F6rg

--=20
J=F6rg Barfurth                         joerg.barfurth@attglobal.net
-------------- using std::disclaimer; -----------------------------
Download:     StarOffice 5.2 at       http://www.sun.com/staroffice
Participate:  OpenOffice now at       http://www.OpenOffice.org

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]