From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20209 invoked by alias); 16 Apr 2002 21:41:37 -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 20085 invoked from network); 16 Apr 2002 21:41:29 -0000 Received: from unknown (HELO zwingli.cygnus.com) (208.245.165.35) by sources.redhat.com with SMTP; 16 Apr 2002 21:41:29 -0000 Received: by zwingli.cygnus.com (Postfix, from userid 442) id C985E5EA11; Tue, 16 Apr 2002 16:41:01 -0500 (EST) From: Jim Blandy To: gdb@sources.redhat.com Subject: C++ namespace using directives Message-Id: <20020416214101.C985E5EA11@zwingli.cygnus.com> Date: Tue, 16 Apr 2002 14:41:00 -0000 X-SW-Source: 2002-04/txt/msg00273.txt.bz2 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 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. 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?