Topic: namespaces and ambiguities


Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/09/24
Raw View
Helmut Jarausch<jarausch@numa1.igpm.rwth-aachen.de> wrote:
>How clever is a compiler required to be concerning 'identical'
>using declarations?  I couldn't find anything the CD2 draft which
>decides what's correct in the following example
>
>namespace standard     // this will occur with 'std' quite often
>{ void print(int) {};
>  void dump(int)  {};
>}
>namespace A { using standard::print; }
>namespace B { using namespace standard; }
>namespace User
>{ using namespace standard;  // most typical usage of 'using directive'
>  using namespace A;
>  void test()
>  {  print(1); } // egcs-1.1: call of overloaded `print (int)' is ambiguous
>}
>namespace User2
>{ using namespace standard;
>  using namespace B;
>  void test()
>  { print(1); } // egcs has no problems here
>}
>
>The aliases  standard::print and B::standard::print are identical.
>Is the compiler required to recognized that?
>If not, isn't that a severe problem with 'using directives' ?
>If the example in 'User2' should be correct, doesn't this force me
>to prefer 'using directives' over 'using declarations' ?

This is a bug in Egcs.  All aliases of a name refer to a single
declaration, and cannot overload one another.  Only the original
declaration referred to is "real".

In particular, using-declarations don't affect Koenig lookup.
For example, in

  namespace A {
    struct X {};
    void f(X*);
  };
  namespace B {
    using A::X;
    void g(X*);
  }
  int main() {
    f((A::X*)0);  // OK
    g((B::X*)0);  // error
  }

the type X is defined in A, and not in B, so Koenig lookup
using the argument type locates A::f but not B::g.  (Egcs
gets this right, anyway.)

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Boris Schaefer <sbo@psy.med.uni-muenchen.de>
Date: 1998/09/27
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

| the type X is defined in A, and not in B, so Koenig lookup
| using the argument type locates A::f but not B::g.  (Egcs
| gets this right, anyway.)
|

hmmm, what's Koenig lookup ?

--
Boris Schaefer -- sbo@psy.med.uni-muenchen.de

If it ain't baroque, don't phiques it.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/09/28
Raw View
Boris Schaefer <sbo@psy.med.uni-muenchen.de> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>
>| the type X is defined in A, and not in B, so Koenig lookup
>| using the argument type locates A::f but not B::g.  (Egcs
>| gets this right, anyway.)
>|
>
>hmmm, what's Koenig lookup ?

A good place to look up new language features is at

  http://www.ocsltd.com/c++/

However, I can't find where it mentions Koenig lookup.

Essentially, it means that function names, when you call
them, are looked up not only in the places where you would
normally expect, but also in whatever namespaces the argument
types are defined.  The canonical example is operator<<
for ostreams; without Koenig lookup you would have to
say

  std::operator<<(os,3);

but with Koenig lookup you can say

  os << 3;

without mentioning the namespace std, because the type of os,
std::ostream, is defined there.  It has quite far-reaching
effects, though, and enables techniques (and probably bugs,
too) that have yet to be discovered.  Coding-standard rules
will probably need to be invented to prevent the bugs.

The only compiler I know of that implements Koenig lookup,
thus far, is Egcs-1.1.  Some others do it only for operators.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jarausch@numa1.igpm.rwth-aachen.de (Helmut Jarausch)
Date: 1998/09/23
Raw View
How clever is a compiler required to be concerning 'identical' using declarations?
I couldn't find anything the CD2 draft which decides what's correct in the following example

namespace standard     // this will occur with 'std' quite often
{ void print(int) {};
  void dump(int)  {};
}

namespace A
{ using standard::print;
}

namespace B
{ using namespace standard;
}

namespace User
{ using namespace standard;  // most typical usage of 'using directive'
  using namespace A;
  void test()
  {
    print(1);
// egcs-1.1a  says:
// NameSp6.C: In function `void test()':
// NameSp6.C:19: call of overloaded `print (int)' is ambiguous
// NameSp6.C:2: candidates are: print(int)
// NameSp6.C:2:                 print(int)
  }
}

namespace User2
{ using namespace standard;
  using namespace B;
  void test()
  {
    print(1);  // egcs has no problems here
  }
}

The aliases  standard::print and B::standard::print are identical.
Is the compiler required to recognized that?
If not, isn't that a severe problem with 'using directives' ?
If the example in 'User2' should be correct, doesn't this force me
to prefer 'using directives' over 'using declarations' ?

Thanks for clarifying this issue,


--
Helmut Jarausch
Lehrstuhl fuer Numerische Mathematik
Institute of Technology, RWTH Aachen
D 52056 Aachen, Germany


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]