December 1998

What's in a name(space)?

by Gerry Myers

Imagine you've almost finished a program and you decide to add some nice graphics (plots and charts). No problem--you install a professional-looking graphing package and add some function calls to your program to execute the new package. Unfortunately, when you try to compile the application, you get errors that say multiple declarations were found for functions x, y, and z. After some investigation, you realize that both your code and the third-party package have x, y, and z functions. What do you do?

You have several choices (most of them bad). You can globally change all your function, variable, and class names to other, unique names. You can get the graphing package's source code and do the same to it. Or (drum roll, please), you can enclose your declarations within a namespace, which would effectively give all your identifiers unique names.

I programmed C and C++ for many years without using namespaces--I never had to. Only within the last couple years have I found myself putting them to work. As programming languages evolve, different constructs fall in and out of favor with the programming community. Lately, namespaces have seen a rise in popularity due in large part to the C++ Standard Template Library (STL), which uses them extensively. In this article, we'll look at how namespaces work, and explore when you should (or must!) put them to work.

What's a namespace?

Namespaces fill a niche that's hard to work around when you encounter it. You may never need them or you may always need them, depending on your choice of programming tools. Before we look at when and why namespaces are needed, let's briefly review what they are.

A namespace delineates a block of code in which identifiers are unique from the rest of the code. Code outside the namespace block can still reference the variables, functions, or classes inside the block, but their full identifier names must be used.

The syntax of a namespace is simple. You declare the namespace block using the namespace keyword, followed by its name and an interior block of code:

namespace MySpace
{
    int x;
    float SomeFnc()  { ... }
    class SomeClass { ... };
}// end of MySpace namespace block
There's nothing special about the code inside a namespace--it's just like any other code.

Explicit versus implicit

You may have never explicitly used a namespace like that shown in the previous example. However, without knowing it, you almost certainly implicitly use them in every program. If you declare a class or function, you're really declaring a namespace. Any identifiers declared within the class or function are local to that block. If you want to reference the identifiers from outside the class, you need to use the full identifier name, which is the class (namespace) name followed by the identifier.

Unlike class and function blocks, explicit namespaces are concerned only with global identifiers. You can't declare explicit namespaces within a class or function. However, you can nest them, as shown in Listing A, or extend/continue them, as shown in Listing B.

Listing A: Nested namespaces

namespace SpaceA
{
    int i;
    float f;

    namespace SpaceB
    {
        int i;
        float f;
    }  // end of SpaceB

}  // end of SpaceA
Listing B: Extended namespaces
namespace SpaceA
{
    int i;
    float f;
}  // end of SpaceA

int i;
float f;
double d;

namespace SpaceA
{
    double d;
}// end of SpaceA extension

Referencing namespace identifiers

You reference the declarations inside the namespace by placing the name of the namespace and the scope operator before the identifiers, like this:

float f = MySpace::SomeFnc() + MySpace::x;

If such code gets to be too tedious (if you have to make many references to identifiers in the namespace), you can declare your intent to use the namespace for all references until further notice. You do so by placing the command using namespace xyz before the part of your program in which you need to reference the namespace code:

using namespace MySpace;
. . .
float f = SomeFnc() + x;

This method saves you from repeatedly typing the name of the namespace. However, you may still need to use the full identifier name (including namespace) if it happens to be the same identifier used for a different purpose in another portion of the program.

Referencing only a specific identifier

If you don't want (or need) to issue a broad using namespace command, you can specify using namespace for a specific identifier. You might do this if you use only one function or class from the third-party package--but you use it throughout your code. You can issue the broad statement

using namespace MySpace;

or add MySpace:: to the front of the identifier each time you use it. But, the best method may be to place

using namespace MySpace::SomeFunc;

at the top of the module. This line will alert the compiler that any reference to SomeFunc() in that module should be mapped to MySpace::SomeFunc(). The rest of your code will be unaffected and will map to your identifiers.

Try on an alias

Another handy widget in the namespace toolbox is the alias. You can give an alias (nickname) to an existing namespace. For instance, you'll want to do this if a third-party package declares a namespace that's very descriptive and unique--but also very long. How would you like to write

XYZCOMPANY_FINACIAL_UTILITIES_NAMESPACE

before each reference to a package's identifiers? You can shorten such a namespace to one of your own liking by writing the following code:

namespace XYZ = 
  XYZCOMPANY_FINACIAL_UTILITIES_NAMESPACE;

If the company's namespace doesn't depict the certain utilities you use from its package, give the namespace an alias that makes it easier for you to relate to. For example, if you use only a full-blown financial package for loan interest calculations, it may be easier to relate to the namespace if you alias it as follows:

 namespace INT_CALC = XYZCOMPANY_FINACIAL_UTILITIES_NAMESPACE;

You don't need namespaces if...

As we mentioned earlier, you may never need to explicitly use namespaces. (Never may be too strong a word--you're likely to see them crop up sooner or later.) If your projects involve only your own code, you don't need to use namespaces. As long as you can control and track the naming of identifiers, namespaces may be more of a programmatic burden then they're worth. (This assumes that you don't purchase software packages from third-party vendors.) However, it wouldn't be a bad idea to get used to namespaces, because they can help compartmentalize your program.

You should use namespaces if...

If you purchase software utilities to be linked into and used by your project, you may (or may not) run into a problem of duplicate identifiers. Because you probably write literate code (descriptive names for classes, variables, and functions), and the people who wrote the new package you bought probably write literate code, you may end up conflicting on customary identifiers such as GetString(), SetFileName(), or even int i.

If you encounter a duplicate name, the simplest way out is to enclose all your header material within a namespace with a name that no one else would use (such as your initials or name). When the compiler goes through your code, it will prepend your namespace name to the front of all your identifiers when building its identifier list--for example,


int i;

will become

int SomeSpace::i;

Now, you'll have to reference the new identifier names a little differently. Simply place a using namespace command at the top of your implementation (CPP) file; all your identifier usages will be prepended with your namespace name. Presto, no more identifier conflicts!

To tell the compiler that you want to use a non-namespace identifier provided in the third-party package, you simply add the scope resolution operator (::) to the front of the third-party function call. Everything that isn't in a namespace is considered global and can be accessed this way.

 
Tip: Save your users the same trouble
You should add explicit namespaces to your programs and utilities if other people will be using them. If you're producing a third-party product, using namespaces will protect the unsuspecting user from the dilemma of duplicate identifiers.

You must use namespaces if...

There are times when you just can't get around using namespaces. If a third-party software vendor encloses its identifier declarations within a namespace, you have no choice but to use its namespace (or an alias of your choosing) to get to its functions and classes. You can do so using any of the methods we've mentioned.

The C++ STL is gaining popularity lately, and guess what? It's enclosed in a namespace called std. If you want to use any of the templates in the STL, you must become at least vaguely familiar with using namespace. The easiest way to reference the STL identifiers (vectors, lists, deques, and so on) is to place using namespace std; at the top of your module--a pretty painless task.

Conclusion

You may never have needed (or even heard about) namespaces before, but that's about to change. Increasingly, third-party software vendors are using namespaces, which means that you must reference their utilities through that namespace. The C++ Standard Template Library is fast becoming a tool of choice for many software developers, a fact that also forces them to learn about namespaces. Namespaces add a little complexity to your code, but they're worth it--take time to become familiar with this construct and begin putting it to work to improve your applications.