anonymous namespaces : should they be used?

Started by
16 comments, last by legalize 16 years, 7 months ago
Quote:Original post by legalize
Quote:Original post by ToohrVyk
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).


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 SiCrane
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.


Ok, thanks that explains it. [smile]
Advertisement
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 SiCrane
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.


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
--random_thinkerAs Albert Einstein said: 'Imagination is more important than knowledge'. Of course, he also said: 'If I had only known, I would have been a locksmith'.
Quote:Original post by ToohrVyk
Quote:Original post by legalize
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?


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.

My free book on Direct3D: "The Direct3D Graphics Pipeline"
My blog on programming, vintage computing, music, politics, etc.: Legalize Adulthood!

Quote:Original post by SiCrane
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.


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...

My free book on Direct3D: "The Direct3D Graphics Pipeline"
My blog on programming, vintage computing, music, politics, etc.: Legalize Adulthood!

Quote:Original post by legalize
This 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.
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.
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
--random_thinkerAs Albert Einstein said: 'Imagination is more important than knowledge'. Of course, he also said: 'If I had only known, I would have been a locksmith'.
Quote:Original post by ToohrVyk
Quote:Original post by legalize
This 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;

My free book on Direct3D: "The Direct3D Graphics Pipeline"
My blog on programming, vintage computing, music, politics, etc.: Legalize Adulthood!

This topic is closed to new replies.

Advertisement