Archived

This topic is now archived and is closed to further replies.

felonius

Unnamed namespaces

Recommended Posts

I just read in Stroustrup C++ book about unnamed namespaces. Apparently they are anonymous namespaces which immediately after their declaration implicitly is made available via the using directive. My question is, why would I ever use an unnamed namespace? What would I achieve? The only things I can think if is that it is kind of a short cut for declaring all global things static. Any thoughts? [edited by - felonius on June 9, 2002 1:49:22 PM]

Share this post


Link to post
Share on other sites
In C, when you wanted to have a symbol local to a file, you used the static keyword. That way, you could have, say, several different foo() functions in different files, without name collisions. This is used for, say, helper functions.

Unnamed namespaces are the C++ extension of that idea : any symbol placed in an unnamed namespace (classes, variables, functions...) will be local to the current file.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]

Share this post


Link to post
Share on other sites
Why couldn''t I just declare those functions static too? That would achieve the same effect I would think? Or is it just a short-hand to make a full block static?

It just seems a bit daft to me to add a new feature to C++ just so I don''t have to type the static keyword in front of a set of functions.

Share this post


Link to post
Share on other sites
Namespaces were designed to avoid conflicts in names ("I cannot use the name ''foo()'' because X already used it in module Y"), while preserving convenience (you can declare which namespaces you''re using at any moment, removing the prefixes).

That''s why all the standard functions and classes are in the namespace std, with their helper functions often further hidden in, say std:rivate : cout is really named std::cout but, within the namespace itself, you can refer to it as cout; and outside, you can either write using std::cout; or using namespace std; to unambiguously indicate that you want to use std::cout as opposed to fruny::cout or felonius::cout.

(using-declarations are also used to disambiguate conflicts when you inherit from two classes with identical member-functions).

The unnamed namespace is just a special case of namespaces. The namespace doesn''t have a name, therefore you cannot access the functions which are in it. The file in which the namespace is declared has an exemption for that, with an implicit using-declaration.

If you''d rather, think about the fact that static takes different meaning depending on where it is found (static local var vs. static global var). That is clumsy and error-prone.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]

Share this post


Link to post
Share on other sites
The alternative to namespaces is to manually mangle your function, variables and class names so that they do not conflict with others, and yet can still be accessed :


// Module A
class Foo_A {...}
int Bar_A;
int Baz_A( Foo_A& );

// Module B
class Foo_B {...}
int Bar_B;
int Baz_B( Foo_B& );

...

// Use Foo_A;
Foo_A a;
Baz_A( a );

// Use Foo_B;
Foo_B b;
Baz_B( b );


The disadvantage is that you can never get rid of the _A or _B, even when you are working _within_ the module. In production code, module names are usually more expressive (and longer) than A or B, but you'd have to drag them along nonetheless.


// Module A
namespace A
{
class Foo {...}
int Bar;
int Baz( Foo& ) {...}

// can use Foo, Bar, Baz without the A:: scope resolution
};

// Module B
namespace B
{
class Foo {...}
int Bar;
int Baz( Foo& ) {...}

// can use Foo, Bar, Baz without the B:: scope resolution
};

...

// Use A::Foo and A::Baz with full scope resolution
A::Foo a;
A::Baz( a );

// Use B::Foo and B::Baz with full scope resolution
B::Foo b;
B::Baz( b );

// Import only A::Foo
using A::Foo a;
Foo a;
A::Baz( a );

// OR, declare we're using A locally :
using namespace A;
Foo a;
Baz( a );

(note: importing both A and B, or (say) A::Bar and B::Bar with cause a name conflict, caught by the compiler)


Furthermore, you can use namespace aliases... (e.g. for library versioning )

namespace Local = A;
Local::Foo a;
Local::Baz( a );


which let you change what namespace you're using at a single point (e.g. with a #if/#endif block).

Unfortunately, VC++ does not implement Koenig lookup

Edit: Koenig lookup is, automatically select A::Baz or B::Baz depending on whether you passed an A::Foo or a B::Foo.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]


[edited by - Fruny on June 9, 2002 2:31:51 PM]

[edited by - Fruny on June 9, 2002 2:33:34 PM]

Share this post


Link to post
Share on other sites
yeah, yeah, I see all the good points of using namespaces (and I use them a lot myself) but I really don''t see any reason to use a *unnamed* namespace, except as a replacement for the global-var/function use of the static keyword. So, if you have a large block of functions and global variables that you want to keep private to a single file then using a unnamed namespace may be a cleaner way to express this fact.

>> Don''t forget that C++ standard deprecates the use of the keyword static in namespaces and global scope.

What does this mean? Have they declared that we should use the static keyword more for this purpose?

>> If you''d rather, think about the fact that static takes different meaning depending on where it is found (static local var vs. static global var). That is clumsy and error-prone.

I know. A book I once wrote that among other things taught C++ programming made a note about this fact since it tends to confuse newbies. I have been coding C++ for 8 years and I seem to find some odd new thing with it at least once a week.

Share this post


Link to post
Share on other sites
quote:
Original post by felonius
>> Don't forget that C++ standard deprecates the use of the keyword static in namespaces and global scope.

What does this mean? Have they declared that we should use the static keyword more for this purpose?



The opposite
quote:
From the Jargon file
deprecated adj.

Said of a program or feature that is considered obsolescent and in the process of being phased out, usually in favor of a specified replacement. Deprecated features can, unfortunately, linger on for many years. This term appears with distressing frequency in standards documents when the committees writing the documents realize that large amounts of extant (and presumably happily working) code depend on the feature(s) that have passed out of favor.



You are supposed to use static only in the static-local-variable context.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]


[edited by - Fruny on June 9, 2002 2:56:12 PM]

Share this post


Link to post
Share on other sites
Silly me. That was a typo. It should have said "shouldn''t" not "should". So that was what I guessed.

Is there anywhere I can see that they (the C++ standard commitiee) in fact think it is deprecated?

Share this post


Link to post
Share on other sites