From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30586 invoked by alias); 22 Apr 2002 21:52:59 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 30576 invoked from network); 22 Apr 2002 21:52:58 -0000 Received: from unknown (HELO cygnus.com) (205.180.83.203) by sources.redhat.com with SMTP; 22 Apr 2002 21:52:58 -0000 Received: from theotherone.redhat-remotie.org (romulus.sfbay.redhat.com [172.16.27.251]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id OAA00501; Mon, 22 Apr 2002 14:52:51 -0700 (PDT) Received: from localhost (localhost.fidalgo.net [127.0.0.1]) by theotherone.redhat-remotie.org (Postfix) with ESMTP id 92155BB537; Mon, 22 Apr 2002 14:52:39 -0700 (PDT) Date: Mon, 22 Apr 2002 14:52:00 -0000 From: Don Howard X-X-Sender: To: Jim Blandy Cc: Subject: Re: C++ namespace using directives In-Reply-To: <20020416214101.C985E5EA11@zwingli.cygnus.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2002-04/txt/msg00370.txt.bz2 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