Understanding namespace scope in c++ - c++

When I run this below code snippet, the output is a is 6. But since I have used namespace n1, which also has variable by name "a", shouldn't the output be a is 5. Am I missing something ?
#include <iostream>
using namespace std;
namespace n1{
int a = 5;
}
int main(void){
int a = 6;
using namespace n1;
cout<<"a is "<<a<<endl;
return 0;
}
But if I use fully qualified name in cout i.e cout<<"a is "<<n1::a; the output is as expected i.e. 5. What is the purpose of using namespace ?

The using directive is a hint to the compiler for places where it should search the name a.
This way, the name look-up will be done in this order:
First search for a in the local scope
If a isn't found, search in the namespace n1
If there's still no a found, look in the global namespace
Without the using directive you provided, the second step wouldn't be performed.
In your case, as there is actually a variable (but it could be anything, we're talking about names) named a, it doesn't go any further.

The rule is simple:
"Local variables always shadow/hide the variables in other namespaces or global variables with same name."
Within the scope in which local variable a is declared, the using directive has no effect w.r.t the symbol name a. It still does import all the symbol names from namespace n1 within the current scope but the local variable a still hides n1::a. So n1::a is simply not visible and you need to use the fully qualified name for it.

when a variable is defined in the local namespace (a in main is in your local namespace) it will prefer it.
So in this case you must tell it (I would like the a from the n1 namespace n1::a)
if you remove the a it will work as expected...

Related

error: cannot resolve overloaded function based on conversion to type ‘int’

I wrote the following code :
#include<bits/stdc++.h>
using namespace std;
int lengthOfLastWord(string A) {
int m= A.size();
int i=0;
while(i<m)
{
if(A[i]==' ')
{
int count=0;
i++;
while(A[i]!=' ')
{
count++;
i++;
}
}
else
i++;
}
return count;
}
int main()
{
string A;
getline(cin,A);
cout<<lengthOfLastWord(A);
}
But it is showing the following error
error: cannot resolve overloaded function ‘count’ based on conversion to type ‘int’
I am unable to understand why is it showing this error and what should I do to fix it.
Please help me.
Thankyou
Inside the if scope, your count variable is colliding with (technically "shadowing") std::count. However, your local count does not exist in the scope of your return statement, so the compiler is trying to use the only count that it knows about at that point, which is std::count.
This is a great example of why using namespace std and #include<bits/stdc++.h> are both bad ideas. If proper includes and namespaces were used, this code would have given you a much clearer compile error:
error: 'count' was not declared in this scope
The most direct reason is because your count variable is defined in the if scope, and not available in the scope of return statement.
However, the error you are seeing is confusing, since you have using namespace std in your code, and it makes completely unrelated (for your purposes) function std::count visible everywhere in your program, including your return statement. From the compiler perspective, you are trying to return a pointer to std::count, but since this function is overloaded template, compiler doesn't know which one you are trying to return - thus the phrasing of the errror.
If you remove the using namespace std from your code, which you should have never had in the first place, your code will still fail to compile, but error message would be way more easier to understand.
One solution is to rename your count variable to something else like total.
The compiler is considering std::count function instead of the count variable which is int.

variables defined in a scope v.s. namespace variables injected in that scope

When I run this code, it displays 6...
#include <iostream>
namespace X {
int p = 5;
}
using namespace X;
int p = 6;
int main()
{
std::cout << ::p;
return 0;
}
However, when I run this code, it displays 5...
#include <iostream>
namespace Y {
int p = 16;
}
namespace X {
int p = 5;
using namespace X;
}
int main()
{
std::cout << X::p;
return 0;
}
Can anyone explain what's happening there? Why am I not getting any error about ambiguity?
First, your question itself. In the first example, you use...
std::cout << ::p;
That prepended :: resolves namespaces in a specific order, starting with the local namespace. (See this answer). Thus, it looks for p globally, locally, and then in an external namespace (X). Because it found p locally, it stops looking.
In the second example, you are explicitly resolving your namespace:
std::cout << X::p;
Thus, there's no search order to be bothered with. It is just going to look for p in the namespace X, and fail otherwise.
This leads to the second problem: you appear to be confusing the purpose of the using namespace keywords. Those are intended to enable you to use a more shorthand approach of resolving to a namespace, instead of always using the fully qualified name (x::p).
However, the computer will still look in the local namespace first, and THEN the using namespaces in the order they are found. As always, once the computer finds the thing named in a namespace, it stops looking.
This leads to a major principle in C++: don't use using namespace! There are exceptions, but you'll pick up on those as you work. The issue comes down to ambiguity as to what namespace something will be coming from, which is exactly the problem you described.
For example, imagine you define the namespaces X and Y in separate classes, and then you simply have the following...
#include "x.hpp"
#include "y.hpp"
using namespace x;
using namespace y;
int main()
{
std::cout << p << std::endl;
}
Where'd p come from? Looking at x.hpp and y.hpp, you see that BOTH havep, so which one is used? And then, what if you addusing namespace z;above them? Now you have to check ifzhasp`. ARGH!
(See this answer for more information on namespace resolution.)
It is important to note that, as far as the compiler/linker are concerned, there is no ambiguity. It has an implicit resolution order to handle that. The ambiguity is all on the coder.
Even worse, what if you define q locally, without realizing that x or y have a q as well? What will it resolve to?
This is a situation you never want to create! Borrowing from Tim Peter's Zen of Python (albeit, different language, but some of the principles therein are true in most languages)...
Explicit is better than implicit.
So, how can we write this to be less wibbly-wobbly timey-wimey?
Drop using namespace. The only time you should even touch this is if you are using a bunch of stuff from one namespace, and virtually nothing from anywhere else. (You'll notice most C++ programmers won't even do using namespace std;)
Use the fully qualified name on anything you use sparingly-to-moderately. For example, x::p.
If you use something a lot, use the command using x::p at the top of the file. This resolves p to namespace x, without confusing everything else.
In short, you should be able to tell, at a glance, what namespace everything comes from. Never create a situation of ambiguity and implicit resolution; only bugs and pain lie that way.

string declaration before main funciton in C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i'm new to understanding stri and declaring them. can a string variable = "" ;
i'm confused why you could put a equal sign on a declaration also. is this to declare a function to be empty sort of like a global variable? like int variable = 0; is that sort of like a global string variable? once i change it it'll be stored down in main function and other fucntions?
#include<iostream>
using namespace std;
string variable = "";
int main() {
return 0;
}
The statement you're asking about defines a variable in
namespace scope (in this case, the global namespace). It's more
or less like any definition: except with regards to linkage and
lifetime:
The lifetime is static, which means that the variable will be
initialized before main is entered (in practice, anyway),
and will be destructed after exit is called.
The linkage is external, which means that the name variable
always refers to the same entity, even in different translation
units.
And of course, since the scope is namespace scope, the variable
can be directly referred to from any function in that namespace,
or in any namespace nested in that namespace. And since all
other namespaces are nested in the global namespace, that means
that the variable can be referred to everywhere (unless some
other declaration is hiding it).
You can assign value to a string variable in two ways.
string variable = "";
This means that you declared a variable named variable of type string and you assigned an empty string to this variable.
You can also assign value this way
string variable("");
this means exactly the same as the one above. but here you don't need the equal sign.
Here's a reference which can help you understand strings http://www.cprogramming.com/tutorial/string.html
There are four separate parts to the small example you posted:
1) Include the necessary headers:
#include<iostream>
2) Declare any used namespaces:
using namespace std;
3) Now this is what you are probably asking about:
string variable = "";
This line above is completely independent of the function below. It is declaring a global variable called variable, of type string. It is also assigning a value to it, which just happens to be the empty string i.e. "". You could also have said instead:
string variable = "My name is numLOCK";
So you are just initializing the value of that variable to the specified text assigning aome value to the variable.
4) Next comes the main function. This does the actual work.
int main() {
return 0;
}
Note that you can use the global variable declared above in your main or any other function. You can also declare more variables inside the function. For example:
string someText = "My name is numLOCK";
int main() {
int someNumber = 42;
cout << someText << endl;
cout << someNumber << endl;
return 0;
}
This will print out:
My name is numLOCK
42

Namespaces confusion

I am new to namespaces and was trying this from C++ Primer
#include<iostream>
namespace Jill
{
double bucket;
double fetch;
struct Hill{ };
}
double fetch;
int main()
{
using namespace Jill;
Hill Thrill;
double water = bucket;
//double fetch; //<<<<<<<<<<<<//
std::cin>> fetch;
std::cin>> ::fetch;
std::cin>> Jill::fetch;
std::cout<<"fetch is "<<fetch;
std::cout<<"::fetch is "<< ::fetch;
std::cout<<"Jill::fetch is "<< Jill::fetch;
}
int foom()
{
Jill::Hill top;
Jill::Hill crest;
}
When the line marked //<<<<<<<<<<<<// is not commented I get expected results. i.e. the
local variable hides the global and Jill::fetch. But when I comment it out, there are 2 fetch left . global fetch and Jill::fetch. And the compiler gives the error
namespaceTrial1.cpp:17:13: error: reference to ‘fetch’ is ambiguous
namespaceTrial1.cpp:9:8: error: candidates are: double fetch
namespaceTrial1.cpp:5:9: error: double Jill::fetch
namespaceTrial1.cpp:20:26: error: reference to ‘fetch’ is ambiguous
namespaceTrial1.cpp:9:8: error: candidates are: double fetch
namespaceTrial1.cpp:5:9: error: double Jill::fetch
My question is why does the compiler get confused this lead to ambiguity? Why does it not assume fetch as just Jill::fetch , since I have added using namespace Jill at the start of main()
If I use declarative using Jill::fetch; at the start of main, the issue gets solved. because using Jill::fetch makes it as if it has been declared at that location. So, its like there is a local fetch variable. [Am i correct?] Why does using declaration behave as if the variable was declared at that location and using directive doesnt?
When you declare a local variable shadowing a global/namespace variable, you explicitly tell the compiler about that. However, when you are using using the variables of the namespace doesn't actually end up in the local scope.
From the specification (section 7.3.4, point 3):
A using-directive does not add any members to the declarative region in which it appears.
Also (from same section, point 6):
If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed.
The using directive modifies name lookup in a way that isn't exactly intuitive to most programmers. The standard says this in [namespace.udir]p2:
During unqualified name lookup (3.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace.
This wording means that names from the namespace do not appear in the current scope, but in some outer scope. In your example the using directive is in the function which is in the global namespace, and the Jill is also in the global namespace, so the names from Jill appears as if they are in the global namespace. (As Joachim said, the names aren't actually introduced there, so they don't immediately conflict with existing names and you only get ambiguous lookups when you actually use them.)
This is a simple case and the compiler gives you an error, which is good. It can actually get more complicated than that.
namespace Outer {
namespace Mid1 { int i = 1; }
namespace Mid2 {
namespace Tricky {
int i = 2;
namespace Inner {
void f() {
using namespace Mid1;
std::cout << i;
}
}
}
}
}
This will output 2, not 1, even though you had the using directive right next to the line referring to i. But the nearest enclosing namespace that contains both Mid1 and the using directive is Outer, so Mid1::i acts as if it was declared in Outer. If you had an Outer::i it would be shadowed by Tricky::i, and Mid1::i fares no better.
An easy solution is to ban using directives and only use using declarations and namespace aliases. They're far more intuitive.
using namespace will not give priority to names it imports resulting in what you already observed.
Getting ambiguity error here is language design decision: it would be rather dangerous for such prioritization to exist. Imagine that the Jill namespace is a large one maintained by several developers probably from different organization. You have no or limited control to its contents and still changes to it might silently change the meaning of your program.
[basic.scope.declaration] says that a local variable hides the global, after it's declaration
int j = 24;
int main() {
int i = j, j;
j = 42;
}
the identifier j is declared twice as a name (and used twice). The declarative region of the first j includes the entire example. The potential scope of the first j begins immediately after that j and extends to the end of the program, but its (actual) scope excludes the text between the , and the }. The declarative region of the second declaration of j (the j immediately before the semicolon) includes all the text between { and }, but its potential scope excludes the declaration of i. The scope of the second declaration of j is the same as its potential scope.
This explains why there isn't an error when you declare a local variable.
When the local variable is not declared, then you have a name clash. The compiler can not decide which fetch to pick, and throws an error.

Why is this c++ working? (variables with the same name)

Alright, I wanna know why this code is working, I just realized that I have two variables with the same name within the same scope.
I'm using g++ (gcc 4.4).
for(int k = 0 ; k < n ; k++)
{
while(true)
{
i = Tools::randomInt(0, n);
bool exists = false;
for(int k = 0 ; k < p_new_solution_size ; k++)
if( i == p_new_solution[k] )
{
exists = true;
break;
}
if(!exists)
break;
}
p_new_solution[p_new_solution_size] = i;
p_new_solution_size++;
}
The k in the inner for loop shadows (or hides) the k in the outer for loop.
You can declare multiple variables with the same name at different scopes. A very simple example would be the following:
int main()
{
int a; // 'a' refers to the int until it is shadowed or its block ends
{
float a; // 'a' refers to the float until the end of this block
} // 'a' now refers to the int again
}
Alright, I wanna know why this code is working, I just realized that I have two variables with the same name within the same scope.
You seem confused about scopes. They're not "within the same" scope... the for loop's k has it's own nested/inner scope. More importantly, to see why the language allows it, consider:
#define DO_SOMETHING \
do { for (int i = 1; i <= 2; ++i) std::cout << i << '\n'; } while (false)
void f()
{
for (int i = 1; i <= 10; ++i)
DO_SOMETHING();
}
Here, the text substituted by the macro "DO_SOMETHING" gets evaluated in the same scope as i. If you're writing DO_SOMETHING, you may need its expansion to store something in a variable, and settle on the identifier i - obviously you have no way of knowing if it'll already exist in the calling context. You could try to pick something more obscure, but you'd have people using such convoluted variable names that their code maintainability suffered, and regardless sooner or later there would be a clash. So, the language just lets the inner scopes introduce variables with the same name: the innermost match is used until its scope exits.
Even when you're not dealing with macros, it's a pain to have to stop and think about whether some outer scope is already using the same name. If you know you just want a quick operation you can pop it an indepedent (nested) scope without considering that larger context (as long as you don't have code in there that actually wants to use the outer-scope variable: if you do then you can sometimes specify it explicitly (if it's scoped by namespaces and classes, but if it's in a function body you do end up needing to change your own loop variable's name (or create a reference or something to it before introducing your same-named variable)).
From the standard docs, Sec 3.3.1
Every name is introduced in some portion of program text called a declarative region, which is the largest part of the
program in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the
same entity. In general, each particular name is valid only within some possibly discontiguous portion of program text
called its scope. To determine the scope of a declaration, it is sometimes convenient to refer to the potential scope of
a declaration. The scope of a declaration is the same as its potential scope unless the potential scope contains another
declaration of the same name. In that case, the potential scope of the declaration in the inner (contained) declarative
region is excluded from the scope of the declaration in the outer (containing) declarative region.
It might sound confusing in your first read, but it does answer your question.
The potential scope is same as the scope of the declaration unless another (inner) declaration occurs. If occurred, the potential scope of the outer declaration is removed and just the inner declaration's holds.
Hope am clear and it helps..
Because you are allowed to have two variables of the same name within the same scope, but not within the same declaration space. The compiler takes the most-local variable of the appropriate name, similar to how you can 'hide' global variables of name X with a member variable of name X. You should be getting a warning though.
In C/C++ the variable scope is limited by the braces so the following code is valid for the compiler:
int k()
{
int k;
{
int k;
{
int k;
}
}
}