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.
Related
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.
I have a simple question for namespace in C++. There are errors when I compiling the following little piece of code. I don't understand why. Thanks for any help in advance!
#include <iostream>
using namespace std;
int x=100;
namespace first
{
int x=1;
}
namespace second
{
int x=2;
}
int main(){
{
using namespace first;
cout<<x<<endl;
}
{
using namespace second;
cout<<x<<endl;
}
cout<<x<<endl;
}
If I comment out the x declared in the global scope and the last statement. It works fine. But in my mind, the first x is declared in the std namespace and using namespace first and second in the main will be invalid after the the code block they are declared(so the namespace will be std again). So the above code should work. Where am I wrong?
But in my mind, the first x is declared in the std namespace
Your mind is wrong. The using namespace std makes names from std available in the global namespace, it doesn't mean names declared in the global namespace are in std.
x is declared in the global namespace.
so the namespace will be std again
No, nothing in your file is in namespace std, only the contents of <iostream> are in namespace std.
The error is that when you try to use x there are two different variables in scope, ::x and first::x that you could be referring to, so it is ambiguous. You can disambiguate with a using declaration instead of a using directive:
{
using first::x;
cout<<x<<endl;
}
This says that in that scope x refers to first::x
in this case x variable is ambiguous. The compiler can't find which x you are going to use. You can write like this.
#include <iostream>
using namespace std;
int x=100;
namespace first
{
int x=1;
}
namespace second
{
int x=2;
}
int main(){
{
cout<<first::x<<endl;
}
{
cout<<second::x<<endl;
}
cout<<x<<endl;
}
now your code will compile.
The first x is not in the std namespace. It would only be in the std namespace if defined like this:
namespace std
{
int x;
}
Because it's not in that namespace, it's matched by references to x later in the program, and such references become ambiguous when another namespace declaring x is also being used (as in using namespace first / second).
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
}
With using namespace I make the whole contents of that namespace directly visible without using the namespace qualifier. This can cause problems if using namespace occurs in widely used headers - we can unintendedly make two namespaces with identical classes names visible and the compiler will refuse to compile unless the class name is prepended with the namespace qualifier.
Can I undo using namespace so that the compiler forgets that it saw it previously?
No, but you can tell your coworkers that you should never have a using directive or declaration in a header.
As others said, you can't and the problem shouldn't be there in the first place.
The next-best thing you can do is bring in your needed symbols so that they are preferred by the name look-up:
namespace A { class C {}; }
namespace B { class C {}; }
using namespace A;
using namespace B;
namespace D {
using A::C; // fixes ambiguity
C c;
}
In some cases you can also wrap the offending includes with a namespace:
namespace offender {
# include "offender.h"
}
No, C++ Standard doesn't say anything about "undo". The best you are allowed to do is to limit scope of using:
#include <vector>
namespace Ximpl {
using namespace std;
vector<int> x;
}
vector<int> z; // error. should be std::vector<int>
But unfortunately using namespace Ximpl will bring all names from std namespace as well.
Not to my knowledge... But as a rule I only use "using namespace" in .cpp files.
The closest, that I'll try to use in header files is following:
//example.h
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
/**
* hating c++ for not having "undo" of using namespace xx
*/
#define string std::string
#define map std::map
class Example {
public:
Example (const char *filename);
Example (string filename);
~Example ();
private:
map<string,complicated_stuff*> my_complicated_map;
};
#undef string
#undef map
#endif //EXAMPLE_H_
after all, defines are #undef -able.
There are 2 problems:
1. it is ugly
2. separate #define and #undef for each name from the corresponding namespace are used
As stated you should not use using namespace sth in header files. When you need functionality from a namespace in your implementation you can leverage scopes like this:
void func() {
// some code agnostic to your namespace.
{
using namespace sth;
// some code aware of sth.
}
// some other code agnostic to your namespace.
}
I am working on some code written by a co-worker who no longer works with the company, and I have found the following code: (which I have cut down below)
namespace NsA { namespace NsB { namespace NsC {
namespace {
class A { /*etc*/ };
class B { /*etc*/ };
}
namespace {
class C { /*etc*/ };
}
} } }
I don't understand the purpose of the namespace commands on lines 3 and 8.
Can someone explain what the purpose of an namespace entry with no name is?
Thanks
That's an "anonymous namespace" - which creates a hidden namespace name that is guaranteed to be unique per "translation unit" (i.e. per CPP file).
This effectively means that all items inside that namespace are hidden from outside that compilation unit. They can only be used in that same file. See also this article on unnamed namespaces.