Why does everybody use unanchored namespace declarations (i.e. std:: not ::std::)?
Asked Answered
I

8

31

It seems to me that using unanchored namespaces is just asking for trouble later when someone puts in a new namespace that happens to have the same name as a root level namespace and mysteriously alters the meaning of a whole lot of programs. So, why do people always say std:: instead of ::std::. Do they really mean to be saying "I want to use whatever std is handy, not the root one."?

Here is an example of what I mean:

In fred/Foo.h:

#include <string>

namespace fred {

class Foo {
 public:
   void aPublicMember(const std::string &s);
};

} // end namespace fred

In fred/Bar.h:

namespace fred {
namespace std {  // A standard fred component

class string { // Something rather unlike the ::std::string
   // ...
};

} // namespace std

class Bar {
 public:
   void aPublicMember(std::string &s);
};

} // namespace fred

In oops.cpp:

#include <string>
#include "fred/Bar.h"
#include "fred/Foo.h"  // Oops, the meaning of Foo is now different.

Is that what people want, or am I missing something?

And maybe you say that you should just never name a namespace std. And that's all well and good, but what about some other root level namespace then? Should any root level namespace anybody ever defines anywhere always be off-limits for a sub-namespace name?

To clarify, I won't consider any answer that tells me std is special because I just used it as an example. I'm talking about a general issue, and I'm using std as a prop to illustrate it, though I do admit it's a rather startling prop.

Ibanez answered 2/11, 2009 at 15:23 Comment(1)
FWIW, I just happened to look inside <memory> of VS2022, and they actually DO use a macro _STD in there which expands to ::std:: and then refer to things like so: _STD addressofGateshead
B
20

The practical reason for unanchored namespaces is that one level of namespaces usually is enough. When it isn't, a second level is usually going to be used for implementation details. And finally, even when using multiple levels, they are still usually specified implicitly from root level. ie. even inside namespace ns1, you'd typically refer to ns1::ns2::foo instead of ns2::foo or ::ns1::ns2::foo.

So, for these three reasons the ::ns1 form is redundant in normal cases. The only case where I'd consider it would be in submissions to Boost, because as a Boost author I won't know where my software will be used.

Banjermasin answered 2/11, 2009 at 15:44 Comment(1)
I'm going to accept this one because it's the closest to a real answer. I think the other one was just voted higher because it was funnier. :-) I suspect I should've chosen a different example, or not asked the question in quite the way that I did.Ibanez
S
42

So, why do people always say std:: instead of ::std::

Probably because they never really had problems with ambiguity because of it.

Along the same lines: I never had to include "earth" in my address, and I'm not going to.

You have to draw the line somewhere, and this it is a reasonable assumption that others won't make their own std namespaces, or at least that a library that does won't be very popular. :)

Selfreproach answered 2/11, 2009 at 15:38 Comment(2)
chuckle Well, if I were living in Andromeda and wanted to refer to someone on Earth, I would likely skip out on 'local group', but I would include 'Milky Way', 'Sol System', and 'Earth'.Ibanez
but mankind needs to techno-evolve off this rock before that's a concernSporogenesis
B
20

The practical reason for unanchored namespaces is that one level of namespaces usually is enough. When it isn't, a second level is usually going to be used for implementation details. And finally, even when using multiple levels, they are still usually specified implicitly from root level. ie. even inside namespace ns1, you'd typically refer to ns1::ns2::foo instead of ns2::foo or ::ns1::ns2::foo.

So, for these three reasons the ::ns1 form is redundant in normal cases. The only case where I'd consider it would be in submissions to Boost, because as a Boost author I won't know where my software will be used.

Banjermasin answered 2/11, 2009 at 15:44 Comment(1)
I'm going to accept this one because it's the closest to a real answer. I think the other one was just voted higher because it was funnier. :-) I suspect I should've chosen a different example, or not asked the question in quite the way that I did.Ibanez
E
8

why do people always say std::

Not always. I use string and using ::std::string. So nothing bad if there will be fred::std::string, because I still use std::string. In small cpp-files it could be even using namespace ::std. Sample:

#include <iostream>
using ::std::string;
//using namespace ::std; // good for small cpp-files

int main()
{
  string s = "sometext"; // no leading ::std
}

you should just never name a namespace std

Yes, you shouldn't give a name std to custom namespace.

Eisele answered 2/11, 2009 at 15:30 Comment(0)
E
3

This is so much artificial:

namespace fred {
namespace std {  // A standard fred component

class string { // Something rather unlike the ::std::string
   // ...
};

} // namespace std
} // namespace fred

This Fred would not be able to explain why he did that to the whole team.

To answer your question: people omit first "::" because it is a habit, which saves time and because it is easier to expect that when namespace is used anywhere, then such name is absolute, not relative.

Entertain answered 2/11, 2009 at 15:29 Comment(1)
Fred needs to get hit with a LART.Daren
D
3

Okay, you say that std is only an example. But to me it appears your question is only applicable to a case where somebody does something as evil as overriding std.

Let me provide another example:

namespace logging
{
    // Logs to local file
}

namespace server
{
    namespace logging
    {
        // Logs to remote destination
    }
}

namespace client
{
    namespace logging
    {
        // Logs to local file and to screen
    }
}

In this case, not prepending :: results in default behavior.

Dzoba answered 2/11, 2009 at 15:35 Comment(5)
This is an excellent reason why relative namespaces should be used in some circumstances, I definitely agree.Ibanez
But in your class, what happens when someone creates a namespace 'server' in their namespace 'client' to refer to server related things that the client cares about?Ibanez
@Ibanez I just wanted to show that the answers heavily depend on the example you give for this question. Anyway: I'd say this would be nearly as evil as making up one's own std namespace. One could use "servercom" if it's about commmunication or "serverconf" for configuratione etc. instead of just "server".Dzoba
So that means that nobody should ever name their sub-namespace name the same name as any global level namespace name?Ibanez
No, this must not to be seen as law. As so often it depends... Using std is probably always a bad idea. If you do definitely want to call your namespace the same as another, then you should carefully weigh out the benefits and problems that might arise from that.Dzoba
W
2

In the case of std I wouldn't assume any other namespace with the same name, same classes but different meaning.

In other cases, the leading :: just looks ugly, and makes reading code more difficult (in my opinion). Namespace clashes are too rare to put the :: in front of everything.

Watch answered 2/11, 2009 at 15:28 Comment(0)
I
2

A lot of code is written in the global namespace. If someone really redefines ::std::, it won't matter how you refer to it in that kind of code.

Also, your scenario is both unlikely and easy to work around. Firstly, the convention since there was a 'std' was that you don't use that name. Secondly, if you were to encounter a package that defined the 'std' namespace, you just do this:

#include <package_name.hpp>

namespace package_name {
  using namespace std;
}

namespace my_app {
  class my_class : public package_name::class_of_something {};
}

Or something similar. You might have to explicitly name ::std as std. My point is this: people go about using the un-anchored 'std::' all the time because even the worst-case consequences aren't a big deal, and unlikely at that.

Increscent answered 2/11, 2009 at 15:32 Comment(0)
S
1

In the same way that names prefixed with _ are reserved, consider std:: as good as reserved.

Silverstein answered 2/11, 2009 at 15:45 Comment(2)
Though to be pedantic, not all names prefixed by an underscore are reserved.Driblet
Yes, not all. Should anyone be interested in the fully goriness, read thisSilverstein

© 2022 - 2024 — McMap. All rights reserved.