Anonymous Namespace - c++

A recent thread on SO triggerred this.
An anonymous namespace is considered to be equivalent to
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
I fail to recollect the exact reason as to why it is not equivalent to
namespace unique { namespace-body }
using namespace unique;
Also tried searching (including google) but in vain. Please share any information you have in this regards.

The specification that exists now was introduced in 1995 in N0783 to correct for a corner case. To quote that paper (page 9):
The WP defines the semantics of an unnamed namespace as being equivalent to:
namespace UNIQUE {
// namespace body
}
using namespace UNIQUE;
This is incorrect because it makes the code in an unnamed namespace dependent on
whether the code is in an original namespace or a namespace extension.
namespace {} // If you remove this line, the
// use of ::f below is invalid
namespace {
void f()
{
using ::f;
}
}
The WP should be changed to define an unnamed namespace as being equivalent to:
namespace UNIQUE {}
using namespace UNIQUE;
namespace UNIQUE {
// namespace body
}

Related

shrinking namespace to base

Is there a way to "shrink a namespace"?
e.g.
std::chrono::milliseconds to std::milliseconds by the namespace alone?
i.e.
namespace std = std::chrono
(please disregard the fact that this is modifying std. this is just an example I think everyone can understand)
Add your own alias to std::chrono, external to std:
namespace chrono = std::chrono;
And then use chrono::milliseconds.
It's possible to collapse layers of namespaces by adding an internal namespace alias. The standard library does this:
namespace std {
namespace ranges::views { /* views stuff */ }
namespace views = ranges::views;
}
So that std::ranges::views::filter can also be accesses as std::views::filter.
But that doesn't help here because milliseconds is a type, not a namespace. The only way to collapse the contents of a namespace is with a using-directive (or equivalently, a whole lot of using-declarations):
namespace std {
namespace chrono { /* chrono things */ }
using namespace chrono;
}
Which isn't really a good idea because it could just break name lookup for things - especially if anything in std::chrono is named the same as something in std. This also completely defeats the purpose of having the nested namespace to begin with.
So the equivalent to the inner namespace alias would just be the outer namespace alias:
namespace std {
namespace chrono { /* chrono things */ }
}
namespace chrono = std::chrono;
And now you write chrono::milliseconds instead of std::chrono::milliseconds, without having to break anything in any of those namespaces.
Alternatively, if you really want to just shove everything into the same namespace, do it into a different one:
namespace all {
using namespace std;
using namespace std::chrono;
}
Although, as I said, questionable.
If you have a namespace with some deeply nested name that you want to shorten (and it's a namespace you are allowed to modify). e.g:
namespace my {
namespace deeply {
namespace nested {
namespace ns {
// ...
}}}}
you can simplify it with a namespace alias:
namespace my {
namespace easy = deeply::nested::ns;
}
Is there a way to "shrink a namespace"?
You can give namespace an alias, or you can have using namespace declarations.
e.g.
std::chrono::milliseconds to std::milliseconds
Something like that is possible, but not for the std namespace because you may not put such declarations there.
But this is possible for example:
namespace my {
using namespace std::chrono;
}
and this:
namespace my_chrono = std::chrono;

Understanding TOTW 153 example with namespace polution

In TOTW 153 it is claimed that using namespace in function scope can leak in the global scope,
in other words they claim this is:
namespace totw {
namespace example {
namespace {
TEST(MyTest, UsesUsingDirectives) {
using namespace ::testing;
Sequence seq; // ::testing::Sequence
WallTimer timer; // ::WallTimer
}
} // namespace
} // namespace example
} // namespace totw
roughly equivalent to:
using ::testing::Expectation;
using ::testing::Sequence;
using ::testing::UnorderedElementsAre;
...
// many, many more symbols are injected into the global namespace
namespace totw {
namespace example {
namespace {
TEST(MyTest, UsesUsingDirectives) {
Sequence seq; // ::testing::Sequence
WallTimer timer; // ::WallTimer
...
}
} // namespace
} // namespace example
} // namespace totw
So I expected that if I do this it will compile:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
namespace totw {
namespace example {
namespace {
TEST(MyTest, UsesUsingDirectives) {
using namespace ::testing;
Sequence seq; // ::testing::Sequence
}
} // namespace
} // namespace example
} // namespace totw
Sequence s; //notice no testing::
It does not. So I wonder if I am wrong in replicating the example, or is the TOTW153 example misleading?
My best guess is that their example is "wrong" in a sense that what they claim is roughly equivalent is not really equivalent in a sense I would assume it is.
You are correct that the "transpiled" code could lead one to think that your last snippet should work. But that's not what they meant.
The using ::testing::Expectation etc. are added to the global namespace from the perspective of the TEST scope. In other words, the transpiled code is effectively identical to the original only within the TEST scope. Outside of that scope there is no effect, but the problems they list are still problems (unless you know that neither the TEST scope contents nor the contents of any involved namespaces will ever be changed). In other words, the using introduces potential collisions between all (present and future) symbols in that TEST scope and the symbols (present and future) in all the involved namespaces. Sounds less scary but will still bite you in the long run.

How to use specific members of a namespace?

I am trying to use the directive using namespace NS on a specific member but the compiler doesn't seems to understand so.
This is a very simple sample of code :
namespace NS{
int a;
int b;
}
using namespace NS::a;
int main(){
return 0;
}
Clang compiler returns error: expected namespace name at using namespace NS::a;
a is not namespace. So you can just pull contents of namespace in global namespace with using namespace NS, or pull only a in global namespace with using NS::a.
using namespace NS means that NS is a namespace and you want to have direct access to its scope. So instead of NS::a you can write a directly.
While
using namespace NS::a means that NS is a namespace including another namespace a and you want to have access to variables defined in scope of namespace a !!!

Is it ok to wrap code in anonymous namespaces for using directives? [duplicate]

This question already has answers here:
Is using namespace in an anonymous namespace safe?
(2 answers)
Closed 3 months ago.
I want using namespace std; to apply to classes as well as functions without polluting the global namespace, but I'm wondering if it's an ok approach.
namespace
{
using namespace std;
class S
{
public:
S()
{
cout << "ok";
}
friend ostream operator<<(ostream& os, const S& s);
};
}
Any caveats to this?
It will work but keep in mind the following points:
You should limit its use in a source file, not in a header file (in general you should refrain from using unnamed namespaces in headers since they can easily mess around with your symbol definitions, especially if there are inline functions that use something from the anonymous namespace).
It's a bad practice and adding an additional naming hierarchy layer (i.e. the anonymous namespace) just for laziness is as bad as it sounds.
If it's in header file then it's not preferable as this file could be included in multiple source file. If in some source file then its acceptable
Whilst this looked like a great solution, in my experiments it doesn't do as I expected it would. It doesn't limit the scope of the using directive.
Consider this:
#include <string>
namespace {
string s1; // compile error
}
namespace {
string s2; // compile error
}
string s3; // compile error
int main()
{
}
None of those strings compile because they are not properly qualified. This is what we expect.
Then consider this:
#include <string>
namespace {
using namespace std;
string s1; // compiles fine (as expected)
}
namespace {
string t2; // compiles fine (I didn't expect that)
}
string v3; // compiles fine (I didn't expect that either)
int main()
{
}
So placing a using directive within an unnamed namespace appears to be exactly the same as placing it in the global namespace.
EDIT: Actually, placing a symbol in an unnamed namespace makes it local to the translation unit. So this is why it can't work for the intended purpose.
Therefore it has to be a no-no for headers.
An unnamed namespace doesn't contain the effects of a using-directive:
namespace A {int i;}
namespace {
using namespace A;
}
int j=i,k=::i; // OK
Both qualified and unqualified lookup follow the implicit using-directive for the unnamed namespace and then follow the explicit one within it. Wrapping the unnamed namespace inside another namespace limits the unqualified case to other code within that outer namespace, of course:
namespace A {int i;}
namespace B {
namespace {
using namespace A;
}
int j=i; // OK, as above
}
int j=i, // error: i not found
k=B::i; // OK
However, in either case you might as well write the using-directive outside the unnamed namespace (or not write it at all if it would be problematic, perhaps because it would appear in a header file).
Don't take the decision to use an anonymous namespace just so you can limit the scope of a using directive.
That being said, if an anonymous (or any other) namespace is already there and you want the advantages of the using inside it, it's fine as long as your coding standards okay it.

"using namespace" statement inside an anonymous namespace

When using a using namespace statement inside an anonymous namespace bring the namespace used in to the file scope? Eg:
namespace foo
{
int f() { return 1; }
}
namespace
{
using namespace foo;
}
int a()
{
return f(); // Will this compile?
}
According to 7.3.4 [namespace.udir] paragraph 4 a namespace directive is transitive:
For unqualified lookup nominates a second namespace that itself contains using-directives, the effect is as if the using-directives from the second namespace also appeared in the first.
... and according to 7.3.1.1 [namespace.unnamed] paragraph 1 there is kind of an implicit using directive for the unnamed namespace:
An unnamed-namespace-definition behaves as if it were replaced by
inline namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }
where inline appears if and only if it appears in the unnamed-namespace-definition, all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the entire program.
Thus, the answer is "yes, this is supposed to compile" (and it does with all C++ compilers I tried it with).
Yes.
This is because an anonymous namespace is automatically brought into the containing scope.
Yes, because, as Dietmar Kühl quoted, an anonymous namespace is replaced by its content.
However, you should pay attention that it is replaced exactly where it is declared (edit), so there is no "magic" in this. For example, this won't work:
namespace foo
{
int f() { return 1; }
}
int a()
{
return f(); // Will this compile?
}
namespace
{
using namespace foo;
}