Namespaces in C++

A common problem in large programs is that different modules both want to use the same name at global scope for different things. Namespaces are used to solve this problem. The "namespace" syntax is used to restrict the scope of a collection of names in order to avoid name clashes with other identifiers used elsewhere in the program. Every object or type defined in a namespace has both a "first name" (e.g. "cout") and a last name (e.g., "std").

An object defined outside of every namespace is said to be in the "global namespace" and has no "last name." In the last few years, it has become standard practice to avoid "polluting" the global namespace as much as possible; i.e., keep it empty except for namespaces and perhaps some functions or classes whose types are known to all other components of the program.

Consider Example 1, as repeated below:

namespace myStuff{
   int counter = 0;
   bool foo( ) { return (counter%5 == 0); }
   const int N = 30;
}

int main(){
   for (int i = 0; i < myStuff::N; ++i)
   {
      ++myStuff::counter;
      if ( myStuff::foo() )
         std::cout << myStuff::counter << std::endl;
   }
   return 0;
}
(This example shows only syntax -- it is too small to motivate the need for namespaces.) Here, "counter" is somewhat like a global variable, but safer, because it is wrapped inside the the "myStuff" namespace. Hence, accidental name clashes with it are unlikely.

Notice that you can use something defined in the namespace in code outside the namespace, but to do so, you must specify it uniquely by one of the following 3 techniques.

  1. Refer to it by its full name; e.g.,
    	       std::cout << "Hello, world!\n";
       
    This is the easiest and safest means, but it makes the code somewhat uglier, as in the above example.
  2. Instruct the compiler to automatically use the namespace version of the object in the current context; e.g.,
    	      using std::cout;  // Make this "using declaration" only once.
    	      //...
    	      cout << "Hello, world!\n";   // OK.
      
    This technique is also safe, but a separate declaration is required for each identifier from the namespace. See Example 2.
  3. Instruct the compiler to introduce *all* identifiers in the relevant namespace. E.g., using namespace std; // A "using directive" // ... cout << "Hello, world!\n"; // OK. This technique is the quickest way to get the familiar identifiers all recognizable by their usual short names. The problem is that it introduces a lot of other less familiar names as well, increasing the chances of an accidental name clash with one of your variables.

For another explanation, see pp. 37--38 of Absolute C++ by W. Savitch. The explanation in Carrano's book on pp. 142--144 may also help some. To get the real story, it is best to read Stroustrup.

C++ has changed some the last few years. With the newer library inclusion style (#include <iostream> instead of #include <iostream.h>), all the familiar library-defined objects and types (cout, endl, ostream, exit(), string, etc.) are in the std namespace and are therefore not accessible without the std:: prefix, unless you specifically instruct the compiler to allow you to refer to them by their (usual) short names alone. The using namespace std directive is a crude way of doing this that is generally acceptable only for small examples or small scopes.