Followers 0

# anonymous namespaces : should they be used?

## 17 posts in this topic

In Modern C++ Design (Alexandrescu), an example implementation of an object factory wraps a concrete object creator function and an ID in an anonymous namespace, to hide it from the rest of the programme. This practice, although effective, just seems inherently strange to me, but maybe this is a lack of experience on my part. Instinctively, I do not see why this could not be wrapped in a class instead, which is one of the purposes of a class or struct, to encapsulate and isolate the data and methods. Is it somehow safer to use anonymous namespaces? Is it more efficient when compared to alternatives? Are there situations where there is no choice? Any views? --random Edit--here is a simple example that illustrates my concern:
#include <iostream.h>

namespace
{
int local; // should not collide with other files
}

void func()
{
local = 2;
}

int main()
{
local = 1;
cout<< "local=" << local << endl;
func();
cout<< "local=" << local << endl;
return 0;
}

// results in
local=1
local=2

Is there any difference between unnamed namespaces and globals? [Edited by - random_thinker on September 11, 2007 5:48:23 AM]
0

##### Share on other sites
Anonymous namespaces and global variables are completely orthogonal concepts. Anonymous namespaces restrict an identifier to a single file, while global variables allow global access through a given identifier. You can have a global variable in an anonymous namespace (usable in that file only) or at file scope (usable in all files), just like you can have a class or function in an anonymous namespace.

The advantages of anonymous namespaces are that you don't have link-time collisions (because your identifiers are restricted to a single file) and don't pollute headers with implementation details (like a static class member or nested class would).
1

##### Share on other sites
So in the above code, in theory, if I separated the anonymous namespace to another file, I should get an error when I try to compile?

--random
0

##### Share on other sites
Quote:
 Original post by random_thinkerSo in the above code, in theory, if I separated the anonymous namespace to another file, I should get an error when I try to compile?

To another translation unit, yes. However, the main purpose is (as mentioned before) related to linking, not compiling.
0

##### Share on other sites
Oh I see...so then this code:

// contents of main.cpp#include <iostream>int nfunc();int func(){	return 1;}int main(){	using namespace std;		cout<< "local=" << func() << endl;	cout<< "local=" << nfunc() << endl;	return 0;}// contents of nspace.cppnamespace{	int func()	{		return 2;	}}int nfunc(){	return func();}

Will return:

local=1
local=2

and the linker will not see the symbol func() twice. I guess that unnamed namespaces are a good practice where needed.

thx!

--random
0

##### Share on other sites
Quote:
 Original post by random_thinkerIs there any difference between unnamed namespaces and globals?

Well, "globals" are namespace-level names in the global namespace. The global namespace is a namespace just like any other. It has no spcial properties and participates in overload resolution just like any other namespace.

That means names in an anonymous namespace, in the current namespace, in the global namespace, and in any namespaces currently in scope due to a "using" directive all participate equally in name resolution.

The big difference is when it comes to name conflicts. With a regular namespace (a named namespace or the global namespace) you can always disambiguate by fully qualifying the name with the namespace (eg. ::func1() for a global variable). You cannot do this with the anonymous namespace. There is no way to disambiguate names declared in an anonymous namespace.

Like many tools, this gives you increased power (of protection) at a known cost (inability to disambiguate).

Me, I've learned to use anonymous namespaces frequently. I've been burned too many times having to support an undocumented API. C-with-classes programmers, although evidently in the majority, are not altogether the bunch leading the human race forwards.
0

##### Share on other sites
So let me see if I understand the use...in a practical sense, where a class or other operation needs certain supporting classes, functions and data that are not to be used by any other part of the programme, then these can be wrapped in an unnamed namespace within the same translation unit, and these will be found within that translation unit during the compile phase, but will not be found by the linker. Is that correct?

--random
0

##### Share on other sites
Quote:
 Original post by ToohrVykThe advantages of anonymous namespaces are that you don't have link-time collisions (because your identifiers are restricted to a single file) and don't pollute headers with implementation details (like a static class member or nested class would).

Interesting. I never mucked around with anonymous namespaces. How is it different from declaring the variable static, which also limits its scope to a single file?
0

##### Share on other sites
Quote:
 Original post by legalizeInteresting. I never mucked around with anonymous namespaces. How is it different from declaring the variable static, which also limits its scope to a single file?

It also works with classes and structures, for instance defining two distinct Visitor classes in two different files without the linker doing strange things with them (the sad part about these collisions is that you don't get a 'multiple definition' error, but rather the behaviour of the binary is erratic).
0

##### Share on other sites
Definitions inside a anonymous namespace can still have external linkage, while they don't cause name collisions at link time. This is important for template types which require names with external linkage for certain template parameters.
0

##### Share on other sites
Quote:
Original post by legalize
Quote:
 Original post by ToohrVykThe advantages of anonymous namespaces are that you don't have link-time collisions (because your identifiers are restricted to a single file) and don't pollute headers with implementation details (like a static class member or nested class would).

Interesting. I never mucked around with anonymous namespaces. How is it different from declaring the variable static, which also limits its scope to a single file?

Well, anonymous namespaces are supposed to be used in favour of this use of "static", or so I thought until recently. But one thread made me question this, as they don't seem to map to each other completely. Read more here.

[edit:]

Quote:
 Original post by SiCraneDefinitions inside a anonymous namespace can still have external linkage, while they don't cause name collisions at link time. This is important for template types which require names with external linkage for certain template parameters.

Ok, thanks that explains it. [smile]
0

##### Share on other sites
Quote:
Well, anonymous namespaces are supposed to be used in favour of this use of "static", or so I thought until recently. But one thread made me question this, as they don't seem to map to each other completely. Read more here.

[edit:]

Quote:
 Original post by SiCraneDefinitions inside a anonymous namespace can still have external linkage, while they don't cause name collisions at link time. This is important for template types which require names with external linkage for certain template parameters.

Ok, thanks that explains it. [smile]

Stroustrup specifically forbids the use of static at global or file scope (only recommending it for class/struct or function scope), and recommends the use of unnamed namespaces instead.

As I usually ask Si, do you have a simple example of unnamed namespace (external linkage) combined with template usage? I learn more from studying your examples than a month's worth of class time.

--random
0

##### Share on other sites
Quote:
Original post by ToohrVyk
Quote:
 Original post by legalizeInteresting. I never mucked around with anonymous namespaces. How is it different from declaring the variable static, which also limits its scope to a single file?

It also works with classes and structures, for instance defining two distinct Visitor classes in two different files without the linker doing strange things with them (the sad part about these collisions is that you don't get a 'multiple definition' error, but rather the behaviour of the binary is erratic).

This would be true of functions, classes and structures declared static as well, so I don't think that's the defining difference.
0

##### Share on other sites
Quote:
 Original post by SiCraneDefinitions inside a anonymous namespace can still have external linkage, while they don't cause name collisions at link time. This is important for template types which require names with external linkage for certain template parameters.

OK, I can see the difference here, but I don't see the value yet... I consider myself pretty proficient in C++, but I haven't yet become a "meta programming" guru with all the template stuff. Hell, its been a hard enough slog to get my coworkers to use the standard library...
0

##### Share on other sites
Quote:
 Original post by legalizeThis would be true of functions, classes and structures declared static as well, so I don't think that's the defining difference.

You cannot declare a class or structure as static.
0

##### Share on other sites
Ok, let's pretend you want to embed a string as a non-type template parameter.
template <const char * string>std::string bar(void) {  return string;};int main(int, char **) {  std::cout << bar<"Hello">(); // this is illegal; string literals have internal linkage  return 0;}

So one way to get that to compile is to declare a const char array with external linkage.
extern const char message[] = "Hello";int main(int, char **) {  std::cout << bar<message>();  return 0;}

However, now you've got an exported symbol message that could cause collisions with other translation units, so if you stick it in an anonymous namespace you eliminate the possible collision.
0

##### Share on other sites
Right...so...

// File 'Main.cpp'template <const char * string>std::string bar(void) {	return string;};namespace{	extern const char message[] = "Hello";}int main(int, char **) {	std::cout << bar<message>() << std::endl;	return 0;}// File 'World.cpp"extern const char message[] = " World";

after build and execution, results in:

Hello

I see....

Thx,

--random
0

##### Share on other sites
Quote:
Original post by ToohrVyk
Quote:
 Original post by legalizeThis would be true of functions, classes and structures declared static as well, so I don't think that's the defining difference.

You cannot declare a class or structure as static.

Ah, good point. You can create a static instance of a class or struct, but you can't limit its visibility to a single compilation unit without making it "nameless" and static, i.e.

static struct{    int foo;    int bar;} foobar;
0

## Create an account

Register a new account