This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB 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]

Re: C++ namespace using directives


On Tue, 16 Apr 2002, Jim Blandy wrote:

> 
> Could a C++ person check my understanding of `using namespace'
> directives?
> 
> I'm reading Stroustrup, and the more I read about `using namespace',
> the weirder it gets.  Check this out:
> 
>     namespace A
>     {
>       int x;
>       int y;
>       int z;
>     };
> 
>     void f ()
>     {
>       int *x;
> 
>       {
>         int *y;
>         using namespace A;
> 
>         *x;  /* `x' refers to local x, not A::x */
>         *y;  /* `y` refers to local y, not A::y */
>         z;  /* `z' refers to A::z */ 
>       }
>     }

This example seems correct to me, as the compiler can dis-ambiguate based 
on type-- dereference works on pointers, so x and y must refer to the 
local versions.

> 
> This program is type-correct, so you can see exactly which definitions
> those identifiers refer to.  I ran it through the newest GCC, and it
> didn't complain about ambiguities.  Stroustrup C.10.1 agrees.
> 
> Weird, huh?  Although the `using namespace' directive does make A's
> variables visible, A's bindings are still *shadowed* by local
> variables in blocks that *enclose* the one containing the `using
> namespace' directive.
> 
> So, here's the way I'd describe the effect of a `using namespace'
> directive:
> 
> To look up some identifier X in a scope that has a `using namespace N'
> directive, search for both X and N::X.  If you find more than one
> match, report an ambiguity.  (But see below for a subtlety in the
> definition of an "ambiguity".)
> 
> Now, suppose you've got nested compound statements.  In the absence of
> namespaces, you start at the innermost enclosing block, and work your
> way out looking for a binding.  In the presence of `using namespace'
> directives, you accumulate extra prefixes to search under as you go
> out.
> 
> So in this case:
> 
>     namespace A
>     {
>       int x;
>       int *y;
>     };
> 
>     void
>     f ()
>     {
>       using namespace A;
> 
>       {
>         int *x;
> 
>         *x;  /* `x' refers to local x */
>         *y;  /* `y' refers to A::y */
>       }
>     }
> 
> Since B has no binding for x, the reference in `*x' refers to the
> local x, without ambiguity, even though A is `used' in an enclosing
> scope.


Again, the compiler can deduced this from type info.


> 
> Regarding what constitutes an "ambiguity": if the same declaration
> makes it into a scope under two different names, that's not considered
> an ambiguity.  So the compiler accepts the following without
> complaint.
> 
>     namespace A
>     {
>       int x;
>     };
>     namespace B
>     {
>       using A::x;
>     };
> 
>     void
>     f ()
>     {
>       using namespace A;
>       using namespace B;
> 
>       x;
>     }
> 
> However, if we give namespace B its own `int x' definition, the
> compiler does complain.
> 
> Is this all correct?
> 

Makes sense to me.  Stroustrup's chapter on namespaces has an example that 
is similar to B above.


-- 
dhoward@redhat.com
gdb engineering



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