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]

C++ namespace using directives



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?


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