Anonymous Namespace Class Definition

CIU5_8 picture CIU5_8 · Jul 18, 2009 · Viewed 7.7k times · Source

I was looking over some (C++) code and found something like this:

//Foo.cpp
namespace
{
    void SomeHelperFunctionA() {}
    void SomeHelperFunctionB() {}
    void SomeHelperFunctionC() {}

    //etc...    

    class SomeClass //<---
    {
        //Impl
    };
}

SomeHelperFunction[A-Z] are functions that are only needed in that translation unit, so I understand why they're in an anonymous namespace. Similarly, SomeClass is also only required in that translation unit, but I was under the impression that you could have classes with identical names in different translation units without any sort of naming collisions provided that you didn't have a global class declaration (e.g., in a commonly included header file).

I should also mention that this particular translation unit does not include any headers that might declare a class with an identical name (SomeClass).

So, given this information, could someone please shed some light on why the original programmer might have done this? Perhaps just as a precaution for the future?

I'll be honest, I've never seen classes used in anonymous namespaces before.

Thanks!

Answer

Brian R. Bondy picture Brian R. Bondy · Jul 18, 2009

An anonymous namespace is like the static keyword when it is applied at the global level.

An anonymous namespace makes it so you can't call anything inside the namespace from another file.

Anonymous namespaces allow you to limit the scope of what's within to the current file only.

The programmer would have done this to avoid naming conflicts. No global names will conflict in this way at linking time.

Example:

File: test.cpp

namespace 
{
  void A()
  {
  }
  void B()
  {
  }
  void C()
  {
  }
}

void CallABC()
{ 
  A();
  B();
  C();
}

File: main.cpp

void CallABC();//You can use ABC from this file but not A, B and C

void A()
{
//Do something different
}

int main(int argc, char** argv)
{
  CallABC();
  A();//<--- calls the local file's A() not the other file. 
  return 0;
}

The above will compile fine. But if you tried to write an CallABC() function in your main you would have a linking error.

In this way you can't call A(), B() and C() functions individually, but you can call CallABC() that will call all of them one after the other.

You can forward declare CallABC() inside your main.cpp and call it. But you can't forward declare test.cpp's A(), B() nor C() inside your main.cpp as you will have a linking error.

As for why there is a class inside the namespace. It is to make sure no external files use this class. Something inside the .cpp probably uses that class.