#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]
anonymous namespaces : should they be used?
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:
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).
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).
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
--random
Quote:Original post by random_thinker
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?
To another translation unit, yes. However, the main purpose is (as mentioned before) related to linking, not compiling.
Oh I see...so then this code:
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
// 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
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.
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
--random
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?
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).
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement