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.
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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With