This is reproduced from the October 1995 issue of Overload with a clarification courtesy of Jay Zipnick.
In Overload 8 I promised that I would return to look at namespaces in more detail. When Bjarne Stroustrup presented the proposal to the committee in Munich in July 1993, he said that the feature was simple enough to explain to C++ programmers "in ten minutes" and could be "implemented in ten days". Prior to the Munich meeting, I had implemented most of the namespace mechanism in a day and it seemed very straightforward. However, I, like many other committee members, had not grasped a couple of subtleties of the namespace mechanism and had implemented it incorrectly. Metaware - the only commercial compiler implementation - had also implemented it incorrectly (Metaware's implementation largely agreed with my own!). Let's look at why the confusion arose and how namespaces really work!

First principles

The principle behind namespaces is simple enough: provide a way to partition the global scope to allow mix'n'match between components from different libraries - see my short expose in Overload 8. A namespace may only be defined at file scope or nested directly in another namespace. Names declared inside a namespace can be accessed from outside the namespace by using the fully qualified name.

	namespace ACME
	{
		class Widget ...
	}
	ACME::Widget w;

A namespace can be "unlocked" for the purpose of name lookup with a using-directive, e.g., using namespace ACME; or an individual name can be imported into the current scope with a using-declaration, e.g., using ACME::Resource;

The using-declaration behaves exactly as if the unqualified name had been declared at the point of the using-declaration and it is a synonym for the fully qualified name.

The using-directive says "if name lookup reaches file scope (or namespace scope) before the name has been found, search any and all unlocked namespaces as well as file scope (or the namespace scope we have reached)". In addition, file scope is now deemed a namespace scope, but with a name you cannot utter. This makes the name lookup rules simpler by removing the 'special case' of file scope and we can rewrite the using-directive rule as: "if name lookup reaches namespace scope before the name has been found, search any and all unlocked namespaces as well as current namespace scope".

I'll explain this in more detail below, but first I want to round off the 'feature list'.

A shorter alias for a long namespace name can also be defined, e.g.,

	namespace ACME = a_company_that_makes_everything;

This also allows you to mix'n'match libraries more easily:

	namespace lib = Modena;
	// can easily change to:
	// namespace lib = RogueWave;
	// namespace lib = std;

	// never need to change this:
	lib::string banner;

It all looks so simple, doesn't it? How could we possibly have been confused?


Confusion will be my epitaph

Unfortunately, a using-directive and a using-declaration look similar enough that many people think the directive is some sort of declaration. Barry Dorrans' letter in Overload 9 is typical of many programmers' first reaction to seeing namespaces. Even with hindsight, I don't know what syntax the committee could have picked to avoid this confusion. Part of the basic problem with namespaces is that they look a lot like classes or named scopes: they have a keyword, a "tag" and a brace-enclosed list of declarations:

	namespace MyLib
	{
		class ConfigurationFile
		{
		// ...
		};
		// ...
	}

This naturally leads programmers to expect a namespace to behave in a similar way to a class and at least obey rules of scope. I think this is what causes many programmers to think that a using-directive will somehow be "found" during lookup prior to reaching an outer scope.


Second principles

There has recently appeared - within the committee, at least - an explanation of namespaces that does not so easily give rise to this confusion. Consider a namespace as simply a shorthand for exactly what we want to achieve - separation of names:

	namespace MyLib
	{
		class ConfigurationFile
		{
		};
	}
	namespace YourLib
	{
		class ConfigurationFile
		{
		};
	}

If we didn't have namespaces, we'd probably write this:

	class MyLib_ConfigurationFile
	{
	};
	class YourLib_ConfigurationFile
	{
	};

Here, the names are all in the global scope and "fully qualified" names would simply the the entire name with the prefix (MyLib_ or YourLib_). This is, after all, something like the way that compilers will implement namespaces anyway. Let us now examine what a using-declaration does in this context:

	using MyLib::ConfigurationFile;

becomes equivalent to:

	typedef MyLib_ConfigurationFile ConfigurationFile;

If the name referred to a variable, it would be like having a local reference to the original:

	Type& name = MyLib_name;

or if it were a function, we could have a local delegation function:

	inline Type func(Arg arg)
	{
		return MyLib_func(arg);
	}

(allowing for the subtleties of pass-by-reference and so on). What about the troublesome using-directive? In this imagined context, using namespace ACME; says "if name lookup reaches global scope, look for ACME_name as well as name". Returning to the "confusing" example in Overload 9:

	namespace A
	{
		int j;
	}
	void f()
	{
		int j = 0;
		if (j)
		{
			// using-directive:
			using namespace A;
			j = 0;
		}
	}

Rewriting this to use a prefix instead of a namespace gives:

	int A_j;
	void f()
	{
		int j = 0;
		if (j)
		{
			// using-directive means:
			// look for A_name as well as name
			j = 0;
		}
	}

Clearly, the j in the assignment must refer to the local j because A_j is in an outer scope and name lookup never reaches it. Replace the using-directive with a using-declaration:

	namespace A
	{
		int j;
	}
	void f()
	{
		int j = 0;
		if (j)
		{
			// using-declaration:
			using A::j;
			j = 0;
		}
	}

and then rewrite this to use a prefix instead of a namespace which gives:

	int A_j;
	void f()
	{
		int j = 0;
		if (j)
		{
			int& j = A_j;
			j = 0;
		}
	}

and it should be clear that the j in the assignment now refers to the local reference and hence to the global A_j.


Like a namespace within a namespace

The simile used above can be extended to nested namespaces too:

	namespace A
	{
		int j;
	}
	namespace B
	{
		using namespace A;
	}

The using-directive inside B says "look for A_name as well as B_name". Now if we unlock B with a using-directive ("look for B_name as well as name") we simply end up with a list of possible names to find in the global scope. Even if we use qualified name lookup to look inside B, we can still use this simile to explain the rules: B::j causes a lookup of B_j and since the using-directive in B adds A_name to B_name as possible candidates, we will correctly find A_j as expected. I should point out that qualified name lookup prior to Monterey (July '95) did not work in this manner but it was clearly the intent of the original proposal that it should and synthesis of namespaces relies on that property.


Synthetic libraries

As I explained in Overload 8, one of the goals of namespaces was the ability to synthesise 'new' namespaces from old ones, allowing a company to provide a single standard namespace that all its programs can rely on without worrying about exactly where names really come from. This should provide great benefits to companies that use many different vendors' libraries and have to deal with differences between versions of those libraries (in fact, this was one of the example Bjarne originally gave in '93 to support his proposal). All the differences can be dealt with in one place - the synthesised namespace - and no client code should need to be changed.

See also The Casting Vote: Monterey - July '95.


The nameless ones

Finally, there are unnamed namespaces. They are exactly like other namespaces with two slight differences: their name is unique and cannot be uttered. Each unnamed namespace is implicitly "unlocked" That means that:

	namespace
	{
	}

is absolutely equivalent to:

	namespace UNIQUE
	{
	}
	using namespace UNIQUE;

where UNIQUE is some compiler-generated name (probably with lots of digits and underscores in it!). Since unnamed namespaces effectively do have a name, all the previous explanation applies.


Alas poor static...

The committee have decided that file scope static should be deprecated - marked for possible future removal - because unnamed namespaces provide an alternative that is more consistent with the future direction, or style, of C++. Since file scope static can be implemented by generating a unique prefix for each translation unit and then treating the full names as externally linked, it should be easy to see how unnamed namespace can be used instead:

	static int i;
	static int j;
	// can be treated as:
	int UNIQUE_i;
	int UNIQUE_j;
	// which is equivalent to:
	namespace UNIQUE
	{
		int i;
		int j;
	}
	using namespace UNIQUE;

Still confused?

Ideally, you'd need to go away and try the code examples on your favourite compiler. Unfortunately, only Metaware supports any form of namespaces and that doesn't obey the rules given above. Several major vendors are working on namespaces now - hopefully implementing them the same way - so it shouldn't be too long before we can "play" with this useful, two-year old language feature! [Since this article was written, several compiler vendors do now claim to support namespaces to varying degrees - try it and see!] If you have any questions or comments about the above, I'd like to hear them - perhaps a follow-up article will be necessary?