Accessing a global and namespace variable - c++

I am trying to access variable x using using directive in the following code:
#include <iostream>
using namespace std;
int x = 10;
namespace e {
int x = 5;
}
int main() {
using namespace e; // Because of this line compiler shows error
cout << x;
return 0;
}
In general we use the following line to access x but I am getting error
We can also use using e::x;
But my question is why can't we use using namespace e;

In this example it may seem that using namespace e; makes names from namespace e available in main function scope. However it does not do this. Instead it tries to inject names (during unqulified lookup in main) from namespace e into the nearest enclosing namespace of main and namespace e, to the global namespace that is. Therefore x becomes ambiguous.

Let's start with another example.
const int x = 10;
namespace e {
const int y = 5;
}
int main()
{
std::cout << e::y;
using namespace e;
std::cout << y;
}
There is variable with value 10 and name x in global namespace (which can be referred to as x simply) and variable with value 5 with name y in namespace e (which must be referred to as e::y).
By adding using namespace e;, you inject all names from namespace e into global namespace. This means global namespace now contains names x and y, and namespace e contains name y. You can now refer to variable with value 5 using both y and e::y.
Now, back to your example. If we change y to x:
const int x = 10;
namespace e {
const int x = 5;
}
int main()
{
std::cout << e::x;
using namespace e;
std::cout << x;
}
There is x in global namespace and x in namespace e. By adding using namespace e; you inject all the names from namespace e to global namespace, so now global namespace contains names x and x, and namespace e contains name x. See the problem? Global namespace contains two names x, which confuses the compiler. When you try to print variable under the name x, compiler looks up names in global namespace and finds two x. It cannot choose which one you meant, so it throws error.
This is the main reason why using namespace (particularly using namespace std;) is considered evil. One can easily break working code by updating a library or introducing a new function. Compiler error is best outcome in such a case, but sometimes it's possible that compiler will silently replace one function by another, because it matches better.
You can still access both variables using fully qualified names:
int main()
{
using namespace e;
std::cout << ::x << " "; //x from global with fully quafilied name
std::cout << ::e::x << " "; //x from namespace e with fully qualified name
std::cout << e::x; //not fully qualified, but not ambiguous either - only one x in namespace e
}

Related

Extremely basic question about namespaces in c++

using namespace X;
cout << var;
using Y::var;
cout << var;
So say I have a namespace X and a namespace Y that both contain a variable of type int called var. When I say using namespace X; what I imagine happening is if I use some variable that isn't in the global namescope what basically happens is it goes okay I'm gonna look for var in namespace X but now that I also use Y::var what does this exactly mean? Does that just say var is the same as Y::var? But then in that case what's happening with using namespace X does it not even look for var in there because I said I'm using Y::var?
After the using directive
using namespace X;
the compiler uses the unqualified name lookup to find the name var used in the following statement
cout << var;
And due to the using directive it will find the variable var in the namespace X.
This using declaration
using Y::var;
introduces the variable var from the namespace Y in the current scope and the next statement
cout << var;
will use the variable var from the namespace Y.
Here is a demonstration program.
#include <iostream>
namespace X
{
int var = 1;
}
namespace Y
{
int var = 2;
}
int main()
{
using namespace X;
std::cout << "var = " << var << '\n';
using Y::var;
std::cout << "var = " << var << '\n';
}
The program output is
var = 1
var = 2
That is the using declaration that introduces the variable var in the block scope of the function main hides the declaration of the variable var declared in the namespace X.
In fact the below simplified demonstration program in essence behaves similarly as the above program relative to the name lookup.
#include <iostream>
int var = 1;
int main()
{
std::cout << "var = " << var << '\n';
int var = 2;
std::cout << "var = " << var << '\n';
}
Yes, using Y::var; does hide X::var when you ask for var. The former is as-if Y::var were declared in this scope, the latter only influences unqualified lookup.
using ns_name::name;
using-declaration: makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same class scope, block scope, or namespace as where this using-declaration appears.
Names introduced into a namespace scope by a using-declaration can be used just like any other names, including qualified lookup from other scopes
using namespace ns_name;
using-directive: From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name.

printing global variable in local block

#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<::x; // should print 10;
}
return 0;
}
Is there any way to print x=10 without changing variable names, variable values and position of cout?
I assume this is an academic question (puzzle) because nobody should write code like that. In the same spirit, here's a way to make it print 10 instead of 15 without changing variable names, variable values and the position of cout:
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
#define x x-5
cout<<::x; // should print 10;
}
return 0;
}
Normally you should parenthesize such expressions in macros, like (x-5). In this case, that would be counterproductive :)
No you can't
An inner block, because it is a different block, can re-utilize a name existing in an outer scope to refer to a different entity; in this case, the name will refer to a different entity only within the inner block, hiding the entity it names outside.
Further information here: http://www.cplusplus.com/doc/tutorial/namespaces/
You cannot access x=10 in the inner block where you defined x=5. It can only see x=5 as x=10 is hidden at that point.
Ref: 3.3.7/1
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).
If you don't mind some horrible undefined behaviour, we could make assumptions about where local variables are stored on the stack. This works on my machine™ using g++ without any additional flags (although even -O1 breaks it):
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<*((&x) + 1); // should print 10;
}
return 0;
}
This is based on the assumption that local variables are placed on the call stack (or some other place) consecutively in main memory, in reverse order of declaration. It breaks in many cases, such as having a different order, having x=10 be placed in a register, or x=10 being optimized away entirely because it's unused.
#include <iostream>
using namespace std;
int x = 15;
int main()
{
int x = 10;
{
int x = 5;
}
cout << x; // should print 10;
return 0;
}
you should probably put cout<< to outside

What is the difference between "namespace::fn" and "::fn" without the namespace? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ namespace question
I have seen a couple of examples where there isnt a namespace. What is the advantage of that?
::fn refers to something called fn in the global namespace.
The ::fn refers to something in the global namespace (it is an absolute path). Note you can import stuff into the global namespace using the using <obj>; or using namespace <name>;
The namespace::fn refers to something in a namespace relative to the current namespace (it is a relativepath).
namespace X
{
namespace Y
{
int Z()
{
N::fn();
// Compiler looks for
// ::X::Y::N::fn()
// ::X::N::fn()
// ::N::fn()
//
// The search is done in that order the first found
// is used. Note this is done at compile time only.
::fn(); // Absolute path. No search done.
// looks for `fn()` in the global namespace
fn(); // Relative path no namespace
// Searchs for ::X::Y::fn()
// ::X::fn()
// ::fn()
::X::fn(); // Absolute path no search done.
// looks for `fn()` in the namespace X which must be
// in the global namespace.
}
}
}
you want to use ::fn when you have two variables with this name, one declared inside a function and another at the global scope. So if you want to deal with global fn inside that function (where local fn is declared) you need to call it ::fn in order to distinguish between them
int fn = 5;
int main (int argc, char *argv[])
{
int fn = 10;
std::cout << "local fn is " << fn << " global fn is " << ::fn;
return 0;
}

Namespace search order

I have two namespaces that each have a function with the same name. If from one of the namespaces I want to call the function that matches the best. From a function in NamespaceA, if I call MyFunction(...), of course it uses the one in NamespaceA. However, if I add a 'using NamespaceB::MyFunction', I would then expect the behavior I described. However, what I actually see is that it ALWAYS finds the NamespaceB function, even though I am in NamespaceA. HOWEVER, if I ALSO add a using::NamespaceA (even though I am already in NamespaceA), it works as I'd expect. A demonstration is below. Can anyone explain how this works?
#include <iostream>
namespace NamespaceA
{
void DoSomething();
void MyFunction(int object);
}
namespace NamespaceB
{
void MyFunction(float object);
}
namespace NamespaceA
{
void DoSomething()
{
using NamespaceA::MyFunction; // Note that without this line the lookup always fins the NamespaceB::MyFunction!
using NamespaceB::MyFunction;
MyFunction(1);
MyFunction(2.0f);
}
void MyFunction(int object)
{
std::cout << "int: " << object << std::endl;
}
}
namespace NamespaceB
{
void MyFunction(float object)
{
std::cout << "float: " << object << std::endl;
}
}
int main(int argc, char *argv[])
{
NamespaceA::DoSomething();
return 0;
}
It has to do with the order in which different parts of the program are looked in to find a name. For the situation you mention, it has to do with the scope of the function's top-level block being searched for before the enclosing namespace. Basically, the using declaration brings that name into the top-level scope of DoSomething, and since that scope is looked in before the enclosing namespace scope, then if a matching function is found there, then the enclosing namespace scope isn't considered.
I have glossed over a lot of stuff that isn't relevant in your example (for example, if the argument were not a built-in type then, believe it or not, names from the scope where that type was defined could be considered as well. For the whole story, see section 3.4 here. It's pretty scary, about 13 pages to describe all this stuff; but don't bother with it unless you really are curious, because most of the stuff is there so that it "works the way you expect", more-or-less. That document is not the real Standard but actually a working draft with some corrections, so it is basically the real C++ Standard plus some bugfixes.
i believe namespaces use the same scoping rules as variables. so if you have a local namespace, lookups will happen there first before moving to the outer scope.
i'm not sure what the rules are for the situation where you have imported two namespaces with the same function names, but you should always fully qualify the function calls in that scenario just for clarity, instead of relying on some nuance of the language implementation for namespaces that people may not be familiar with.
Short answer: Local defined name and the name declared by a using-declaration hides nonlocal names.
Detailed answer:
Your question is very interesting. I didn't open standarts of C++98,03,11 for that question, but open Bjarne Stroustrup's book
Namespace - is a named scope. Verbosity can be eliminated using two techniques:
create synonymous with using NS :: x; (using-declaration)
create synonymous for all the variables with using namespace NS :: x; (using-directive)
The answer to your question is here:
Appendix B 10.1
local definitions, and names defined with using-declaration hides
the name of a non-local definitions.
Bonus with opposite situation:
Also if you
using NamespaceA::MyFunction;
using NamespaceB::MyFunction;
change to
using namespace NamespaceB;
Then you due to text below get situation with call only void MyFunction(int object)
8.2.8.2
Names explicitly declared in namespace (also made with using declaration)
have priority over the names made available by using directives
Extra code to play with:
#include <iostream>
// var in global namespace
const char* one = "G_one";
// vars in named namespace
namespace NS1 {
const char* one = "NS1_one";
const char* two = "NS1_two";
const char* three = "NS1_three";
}
namespace NS2 {
const char* one = "NS2_one";
const char* two = "NS2_two";
const char* three = "NS2_three";
}
int main(int argc, char *argv[])
{
using namespace NS1; // using-directive
using namespace NS2; // using-directive
// const char* two = "L_two"; // local namespace
using NS2::two; // using-declaration
// C++ rules
// Local names and names with using-declarations
// takes precedence over the name of the NS
std::cout << "two: " << two << std::endl;
//std::cout << "three: " << three << std::endl; // ambiguous symbol
// But the name in global-namespace does not have priority over imported name from namespace
//std::cout << "one: " << one << std::endl; // ambiguous symbol. Because wGlobal names does not have priority over
return 0;
}

namespaces having unnamed namespace with the same variable declared

I tried this dummy code below to test unnamed namespace.
I have the following output
ctor 1
ctor 0
3
5
I am a bit confused about this.
I was expecting an error from the compiler saying that it cannot resolve
an ambiguity regarding a::m_a. Instead it refers always to the
less nested. Is it always the case? What rules C++ is following?
It seems that the compiler creates variable CMyObj following the order
written on the file. Is this always the case?
is there any way to access the most nested m_a variable
from main()?.
class CMyObj{
public:
CMyObj(int a){std::cout << "ctor " << a << std::endl; }
};
namespace a{
namespace{
int m_a=4;
int m_b=5;
CMyObj m_obj(1);
}
}
namespace a{
int m_a=3;
CMyObj m_obj(0);
}
int main(){
std::cout << a::m_a << std::endl; // which one?
std::cout << a::m_b << std::endl; // how this is possible?
return 0;
}
I don't have C++03 standard with me to check the wording there, so I will quote from FDIS n3290. I think the answer to this question is found in qualified name lookup rules in 3.4.3.2/2:
For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S0(X,m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S0(X,m) is not empty, S(X,m) is S0(X,m); otherwise, S(X,m) is the union of S(Ni,m) for all namespaces Ni nominated by using-directives in X and its inline namespace set.
Now, remember that unnamed namespace is a uniquely named namespace with a using directive.
First look at this simplified code (and my simplified explanation, you can read §3.4.3.2 for the details):
namespace a
{
int x;
}
int main()
{
int i = a::x;
}
Consider what happens when we say a::x. First the compiler enumerates all the declarations of x in a. If it finds an unambiguous x, it finishes successfully. Otherwise it recursively searches the namespaces declared by a using-directive. If it never finds a result, the program is ill-formed.
namespace a
{
int x;
}
namespace b
{
using namespace a;
}
int main()
{
int i = b::x;
}
Here, it doesn't find x in b, so it searches the namespace a (because of the using-directive) and finds it. It should now make sense why this isn't ambiguous:
namespace a
{
int x;
}
namespace b
{
using namespace a;
int x;
}
int main()
{
int i = b::x;
}
Here it finds the x in b and never considers a. Now just consider that an unnamed namespace is actually just a namespace with a unique unknown name:
namespace b
{
namespace
{
int x;
}
// this is what an unnamed namespace expands to (in exposition)
namespace __unique__ {}
using namespace __unique__;
namespace __unique__
{
int x;
}
int x;
}
int main()
{
int i = b::x;
}
Like before, the x in b is found without considering the unnamed namespace. Your code is similar.
I should take time to find the exact definitions in the spec, but when you have an anonymous (unnamed) namespace, the compiler actually generates a mangled name. When you write
a::m_b
in the second std::cout statement, the compiler is automatically substituting the mangled name so you can access it. Incorporating from Gene Bushuyev's subsequent answer:
Now, remember that unnamed namespace is a uniquely named namespace
with a using directive.
In the case of the colliding names, the compiler knows what a::m_a means, so it uses that. It's the one at the top level of the namespace. I don't think there is any way to get to the unnamed namespace copy of m_a at this point.
This page does a decent job of explaining namespaces. Winterdom: On C++ Namespaces
There is no ambiguity because the scope of namespace::<unnamed>::m_a is the outer namespace (namespace::a). There is no way to access namespace::<unnamed>::m_a within the main function and that is why there is no ambiguity. Try the to compile the following code and you'll get the error:
namespace ns{
namespace {
int a = 2;
}
int a = 3;
int c = a;
}
Global variables residing in the same translation unit will be initialized in the order they are declared. Initialization order of global variables declared in different translation units is undefined.