A feature of C++ is the ability to create unnamed (anonymous) namespaces, like so:
namespace {
int cannotAccessOutsideThisFile() { ... }
} // namespace
You would think that such a feature would be useless -- since you can't specify the name of the namespace, it's impossible to access anything within it from outside. But these unnamed namespaces are accessible within the file they're created in, as if you had an implicit using-clause to them.
My question is, why or when would this be preferable to using static functions? Or are they essentially two ways of doing the exact same thing?
From experience I'll just note that while it is the C++ way to put formerly-static functions into the anonymous namespace, older compilers can sometimes have problems with this. I currently work with a few compilers for our target platforms, and the more modern Linux compiler is fine with placing functions into the anonymous namespace.
But an older compiler running on Solaris, which we are wed to until an unspecified future release, will sometimes accept it, and other times flag it as an error. The error is not what worries me, it's what it might be doing when it accepts it. So until we go modern across the board, we are still using static (usually class-scoped) functions where we'd prefer the anonymous namespace.
There is one edge case where static has a surprising affect (at least it was to me). The C++03 Standard states in 14.6.4.2/1:
The below code will call
foo(void*)
and notfoo(S const &)
as you might expect.In itself this is probably not that big a deal, but it does highlight that for a fully compliant C++ compiler (ie. one with support for
export
) thestatic
keyword will still have functionality that is not available in any other way.The only way to ensure that the function in our unnamed namespace will not be found in templates using ADL is to make it
static
.Update for Modern C++
As of C++ '11, members of an unnamed namespace have internal linkage implicitly (3.5/4):
But at the same time, 14.6.4.2/1 was updated to remove mention of linkage (this taken from C++ '14):
The result is that this particular difference between static and unnamed namespace members no longer exists.
In addition if one uses static keyword on a variable like this example:
It would not be seen in the mapping file
Personally I prefer static functions over nameless namespaces for the following reasons:
it's obvious and clear from function definition alone that it's private to the translation unit where it's compiled. With namesless namespace you might need to scroll and search to see if a function is in a namespace.
functions in namespaces might be treated as extern by some (older) compilers. In VS2017 they are still extern. For this reason even if a function is in nameless namespace you might still want to mark them static.
static functions behave very similar in C or C++, while nameless namespaces are obviously C++ only. nameless namespaces also add extra level if indentation and I don't like that :)
So, I'm happy to see that use of static for functions isn't deprecated anymore.