Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use unnamed namespaces in implementation files?

I have defined some functions (no classes involved here) in an external *.cpp file, and of course there is an appropriate *.h file.

Some of the functions in the *.cpp file are used only in that *.cpp file nowhere else. They are not even mentioned in the *.h file.

Should I put those functions into an unnamed namespace or may they live just next to the other functions? And if so, why should I need an unnamed namespace for them? I cannot see a problem, since those functions are not accessible from outside anyway.

like image 665
user1192880 Avatar asked Feb 06 '12 17:02

user1192880


2 Answers

If you want them to be truly private to that compilation unit, put them in an anonymous namespace. If you don't then someone could declare those functions elsewhere and use them explicitly.

Take the following example:

// library.cpp

// a "private" function here, in that it is not declared anywhere
void f() {}

namespace
{
   // same as above, except within an anonymous namespace
   void g() {}
}

// client.cpp

void f();

int main()
{
   // Can call f(), it's been declared and is now effectively "public"
   f();

   // compilation error, this has no idea what g() is, it's not declared 
   // in any scope that can be resolved here
   g();

   return 0;
}
like image 84
Chad Avatar answered Oct 31 '22 03:10

Chad


Your question can be split in two:

1. "How can I hide global functions ?"

One simple way to do that, is NOT to put the header of the function into the header file:

//============================
// Filename: "mylibrary.hpp"
//============================
// Description:
// Utility functions.
//============================
#ifndef MYLIBRARY_H_INCLUDED
#define MYLIBRARY_H_INCLUDED
//============================

namespace MyLibrary
{
    void DoSomething();
} // namespace MyLibrary

//============================
#endif // MYLIBRARY_H_INCLUDED
//============================

Full code file:

//============================
// Filename: "mylibrary.cpp"
//============================
// Description:
// Utility functions.
//============================
// self header include
#include "mylibrary.hpp"
//============================

namespace MyLibrary
{
    void DoSomethingBefore()
    {
      // ...
    }

    void DoSomethingAfter()
    {
      // ...
    }

    void DoSomethingConfirmed()
    {
      // ...
    }

    void DoSomething()
    {
      DoSomethingBefore();
      DoSomethingConfirmed();
      DoSomethingAfter();
    }
} // namespace MyLibrary

//============================
#endif // MYLIBRARY_H_INCLUDED
//============================

When this is compiled, you get a "mylibrary.o" or "mylibrary.obj" file. You may provide it, to other developers as: "mylibrary.hpp" plus "mylibrary.obj", but, without the "mylibrary.cpp" file. Most "plain c" / "c++" compilers can work this way.

There are other ways, read the next section.

2. "Are anonymous namespaces, a good technique to hide global functions ?"

The "Anonymous Namespaces" technique, is another way to hide global functions.

There is a similar question on:

Unnamed/anonymous namespaces vs. static functions

But, personally, I don't recommend this technique, as the "favorite" answer.

Namespaces are one of those things, that I wish existed since the start of "pure c" or "c++". But, "anonymous namespaces" or "unnamed namespaces", seems weird to use.

Its like trying to hide something, and, later, forget, where do you store it.

3 Additional suggestions

(a) I suggest to use a single main REQUIRED, not optional, non-anonymous namespace per file. It may have nested, additional inner namespaces. Each main namespace, should have the same id. as the filename, but, without the file extension or file suffix.

(b) Avoid anonymous namespaces. Its like storing things in a warehouse, without an index.

(c) Use a file extension, or file prefix, in your header files, maybe ".h", or ".hpp", even if if its a c++ file. The standard says c++ shouldn't use an file extension or file suffix on "c++" files, but are difficult to identify or find on the filesystem.

Good Luck.

like image 45
umlcat Avatar answered Oct 31 '22 04:10

umlcat