The below code give the compilation error
namespace X{
int i;
}
void f(){
int i;
using X::i; //compile error 'i’ is already declared in this scope
}
But if i replace this line with using namespace X, it compiles fine.
Can someone help understand differences.
Also in the modified code below, I was expecting the output for X::I to be 100 in all places, but it is not.
May be I have misunderstood the namespace concept ?
namespace X{
int i;
}
void f(){
int i=1;
cout << "local I " << i << endl; // prints 1 OK
using namespace X;
i=100;
cout << "X::i " << i << endl; // prints 100 OK.
cout << "X::i " << X::i << endl; // prints 10 why ?
}
main(){
using namespace X;
i=10;
f();
cout << "X::i " << i << endl; //prints 10 why ?
}
Thanks for any help to make me understand this.
In main():
using namespace X;
i = 10;
This sets X::i to 10.
prints 10 why?
That's ^^ why.
Also, in f(): you have another local variable named i that shadows X::i, that's why i resolves to 1 and 100, respectively, and you can only access the other variable in the X namespace by explicitly specifying its namespace.
When you say 'using namespace X'...
if the variable 'i' is defined in X, then, for all references to the variable 'i', the compiler replaces it with 'X::i'. So in main(), when you say i=10, it's setting X::i to 10.
In f()...
you create a NEW variable called i. This is different from X::i. You set i to 1. Then, you begin using namespace X. However, there is a naming conflict--when you say 'i', should it use the local 'i', or X::i? The C++ compiler handles this such case by identifying the variable 'i' with the LOCAL i. Because there is already an i defined in the function, it cannot introduce another i--the i in the namespace. So, in order to reference X::i, you have to explicitly say 'X::i'. Otherwise it thinks you're talking about the LOCAL i.
In the first example, when you say using X::i, you're not giving the compiler much of a choice. You're saying < I WANT TO CALL X::i 'i' >. However, it can't do this--because there's already an 'i' defined. Forcing the compiler to do this would result in two different variables having the same name--which cannot happen.
Hopefully this clarified things a bit. Comment with additional questions.
The using X::i Statement introduces a particular name into the scope. Apparently, the name i was already used so you will not be able to use it again.
Actually, namespaces are used to avoid possible name-clashing. With such short names, namespaces are actually overkill.
Related
The cout statement in function call swap is not executing. Why?
#include <iostream>
using namespace std;
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
cout << "Value Swapped" << endl;
}
int main() {
int x = 400, y = 100;
swap(x, y);
cout << "x = " << x << " y = " << y << endl;
return 0;
}
I have expected below output:
Value Swapped
x = 100 y = 400
But the output I have got is:
x = 100 y = 400
You're not seeing "Value swapped" because your swap function never gets called. Instead, you're calling std::swap<int>.
If you hadn't said using namespace std;, you'd have found out that your swap function is being passed integers, but was expecting pointers. Reason #1 not to use using namespace std; -- you can easily end up not calling what you think you are. :)
your function swap is expecting pointers as arguments, but you are passing integers. So instead of calling your function, it's calling the c++ swap function. To better understand this, change the function name 'swap' to any other name like 'swapp' and you'll see this error:
invalid conversion from int to int*
write swap(&x, &y) and you'll get your desired output
Consider choosing a unique enough identifier name such that there will not be a conflict with a namespace identifier (as in std::swap). If you can't choose the name of your identifier, put it inside of a namespace.
Secondly, if the compiler does not enforce the function declaration that you state, you should manually check to see that you passed the variables correctly (i.e., &x and &y instead of x and y).
using namespace std imports another equally named function from namespace std into global namespace, so you end up in having two overloads:
swap(int&, int&); // from std; actually a template instantiation
swap(int*, int*);
You call swap as
swap(x, y);
Now consider: Which are the types of x and y, are they pointers? So decide yourself, which overload will get called?
If you hadn't imported the second overload via using namespace std, which generally is considered bad practice anyway (well, you got a victim of the pitfalls of right away...), you would have ended up in a compilation error instead (integers aren't converted to pointers implicitly!).
To get your function called, you need to make pointers from:
swap(&x, &y);
// ^ ^
Actually, that would have worked even with the imported namespace (despite of being bad practice), as the imported overload is a template, yours an ordinary function, thus yours is considered the more specialised overload and thus will be preferred.
This question already has answers here:
variable declaration within the while loop C/C++
(5 answers)
Closed 5 years ago.
Why does this code cause an infinite loop:
#include <iostream>
using namespace std;
int main() {
int y = 5;
while (y < 6) {
int y = 7;
cout << y << endl;
}
}
yet removing the "int" in the while statement makes it run once normally?
(
#include <iostream>
using namespace std;
int main() {
int y = 5;
while (y < 6) {
y = 7;
cout << y << endl;
}
}
)
In this loop:
while (y < 6) {
int y = 7;
cout << y << endl;
}
The inner y is not accessible in the condition test.
If you remove the int in the loop, you're simply assigning a new value to the variable defined outside while, thus terminating it.
Look up Scope on CppReference.
The behaviour you have observed is called shadowing.
This means that a variable is "shadowed" by another variable in an inner scope.
(iBug has already provided a link to the C++ scope rules)
The outer scope (in your case while(y < 6)) can not access the inner scope (in your case int y = 7;) and vice versa. Both have the same name, but they are completely separate variables in separate scopes.
This is a very common source for errors (you also find a lot of them here) and doesn't only happen with loops and other scope brackets, but also very often with class members. Imagine a class:
class MyClass {
int a;
public:
void getA( int a ) { return a; }
};
getA() defines a parameter a, which shadows the class member a. This is at least bad style, but even more probable a source of errors. We don't know - did you want to return the member a or did you really mean the parameter? So this should be avoided.
Here's a real life example on Stackoverflow - see my comment below the question (regarding the 3rd constructor)
Possibilities to avoid these kind of errors are:
Use highest possible compiler warnings and perhaps even warnings as errors. Compilers can warn about those kind of shadowing issues.
Use a name scheme. A common scheme is members with a m, m_ prefix, a _ suffix and the like. If the member name in the MyClass would have been m_a, this would have reduced confusion. Of course this doesn't help in your example, but it's a good idea nevertheless.
This question already has answers here:
variables declaration with same name C++
(5 answers)
Closed 5 years ago.
I understand that two variable can be declared of same name in two distinct function.
how can we declare a variable within a function which is already declared in the global scope?
This is called variable shadowing. In C++, you can use scope resolution operator :: to refer to global variable from inside a block. The C language does not have this, however you may use the following technique to access global variable as well:
#include <stdio.h>
int a = 100;
int main(void)
{
int a = 200;
printf("%d\n", a); // prints 200
// anonymous block used to refer to global a
{
extern int a;
printf("%d\n", a); // prints 100
}
return 0;
}
Even this is possible, be wary, that it may confuse other programmers, i.e. it violates "Don't be clever" principle.
For C++ you can always use the resolution operator to specify what scope you are talking about (::)
However in C the rule is that the variable in the context of the more specific scope is used.
int num = 5;
int main()
{
printf("%d\n", num);
int num = 3;
printf("%d\n", num);
return 0;
}
Prints
5
3
Scope of a variable is the part of he code where that variable is visible.
Therefore a global variable is visible everywhere but a local variable is visible only to a particular section of code.
#include <iostream>
using namespace std;
int a=9;
int main()
{
int a =8;
cout<<a<<endl;
cout<<::a;
return 0;
}
In the above c++ code first output is 8 whereas second is 9.
Here both variables were visible in the code but using scope resolution operator you can decide which variable you actually want.
Said in simple terms, if multiple variables in a program have the same name, then there are fixed guidelines that the compiler follows as to which variable to pick for the execution. I'll go over them all in an example below.
Global variables, as the name suggests are declared outside of any function and are accessible in any part of the code. However, in the event of another variable with the same name as the global one, the local variable would get the higher "preference" for the part of the code that comes after it is declared.
For example,
int num = 25;
class Print
{
int num;
Print();
};
Print::Print()
{
num = 98;
}
void PrintNumber(void)
{
int num = 12;
}
int main(void)
{
cout << num << endl;
int num = 34;
cout << num << endl;
PrintNumber();
Print object;
cout << object.num << endl;
}
I've tried to cover every possible scenario, please don't hesitate to inform me if I missed any scenario out. Anyways, the result of this program would be:
25
34
12
98
The first one is the global one; since the variable num of the class Print and the function PrintNumber() is localized to the object of the class and that function respectively, only the global variable is accessible here. Same for the second number, except a local variable with the same number num has a a higher privilege, so it is given a higher accessibility than the global variable (mind my erroneous English, sorry for that). Then when the PrintNumber() function is invoked, it prints the num of that local variable. Finally, an object of class Print will output the value stored in the num of that class.
Hope this answers your question.
#include <iostream>
using namespace std;
int x=24 ;
int main()
{
int x=0;
{
int x=5 ;
::x= x+2 ;
}
cout<<::x<<endl ;//first
cout<<x<<endl ; // second
return 0;
}
in this simple example i'm using code block and i know i can modify the global variables using Scope resolution operator.
and i modify the global variable in this example but i wonder if there is a way to modify the variables in specific scope like main function (not necessary the( Scope resolution operator) way )
that mean in this example i need the first output is 24 and the next one 7 .
sorry for my english i hope to understand the question
There are no means to access variables from a specific scope in C++.
If you declare an object or a variable in the inner scope with the same name as an object or a variable in the outer scope, then for all intents and purposes that outer scope's object or variable is not directly visible in the inner scope.
If you already have a pointer or a reference to the outer scope's object, of course, you can still access it indirectly. You just cannot access it directly.
This is a fundamental concept of C and C++; but many other programming languages share the same analogous concept.
The scoping rules of C++ are textual and AFAIK you can't do this, as you can't go putting namespaces inside of functions. But introducing a reference with a unique name may help you as a workaround if you find yourself in a bind like this:
#include <iostream>
using namespace std;
int x = 24;
int main()
{
int x = 0;
int & main_outer_x = x;
{
int x = 5;
main_outer_x = x + 2;
}
cout << ::x << endl; //first
cout << x << endl; // second
return 0;
}
That gives you:
24
7
That shouldn't cost any more memory in your generated code, and lets you keep the outer name untouched. Still, likely to be confusing and error prone if you're purposefully having a name collision within a function. This is abstract code so it's hard to criticize, but most concrete code with such a pattern should probably be done another way.
I'm very new to C++ so I'm hoping someone would shed some light. I came across several similar topics but I just need clarification.
So it seems it's valid to pass a local string that has been declared but not initialized to a function. But why does compiler complain when you try it with int or float??
Whether it's string, float, or int, memory address gets referenced when it is declared even tho it may be "garbage"
#include <iostream>
using namespace std;
void load(int);
int main()
{
int salary;
load(salary);
return 0;
}
void load(int sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
If I declare int or float as global variable, it works as expected without any warnings.
So then is it a better practice to declare variable in global space (I hope not)?
So putting it in global, it works :
#include <iostream>
using namespace std;
int salary;
void load(int);
int main()
{
load(salary);
return 0;
}
void load(int sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
ok, another example to show that uninitialized global variable works when passing to function as value : (going off of David's comment)
int foo;
int returnit(int j)
{
cout << "your salary";
cin >> j;
return j;
}
int main()
{
int k = returnit(foo);
cout << k;
return 0;
}
anyways, lesson here is to initialize primitive data types before passing to functions.
So it seems it's valid to pass a local string that has been declared but not initialized to a function. But why does compiler complain when you try it with int or float??
If by "string" you mean a std::string object, it's because objects are never uninitialized. When you do:
std::string s;
then the default constructor of std::string is invoked, and the object is initialized.
Variables of primitive data types (such as int and float), unless declared to have static storage duration, will have garbage if not explicitly initialized, however. Making attempts to read and use that garbage rightly trigger warnings. (Variables of primitive data types that do have static storage duration (i.e., global variables or variables declared as static) are implicitly initialized to 0.)
So then is it a better practice to declare variable in global space (I hope not)?
No, a better practice would be to initialize your variables.
The best way to explain why you should never use an uninitialized variable in a function call is because this is logically invalid and sometimes both logically invalid and the syntax is invalid.
To see if your program is logically valid use the box method and trace your program. Global box has global variables in it, int main has its own box which holds its local variables, and when functions are called create a new box for that function and fill it with its parameters and local variables. Go line by line and change variable values as they change in the program. Remember to use only constants as global variables. When writhing a function be careful when you pass by reference that you understand that the function is given that variables address in memory and can change that value. When using pass by value use this kind of syntax in your functions declaration:
int Multiplication(const int Var1, const int Var2);
This protects the values you pass to multiplication.The syntax of c++ is made for speed, and it does not keep you from being logically incorrect.
int salary;
load(salary);
What value do you think you are passing to load here? You're passing a nonsense value.
To be clear, you are not passing an "uninitialized variable", you are passing the value of an uninitialized variable. If you do:
int j=3;
load(j);
You are passing the value of j, that is, 3, to load. If you don't specify otherwise, C++ passes by value.
You'd have the same problem with a global variable:
int foo;
int returnit(int j)
{
return j;
}
int main(void)
{
int j=returnit(foo);
What value do you think j should have here?! You still have to initialize a variable to some particular value before you can pass its value to a function.
To add on David's answer, what you probably wanted to do (I'm guessing) is to modify the original salary variable. To do this you need to pass a reference to the variable, like this:
void load(int& sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
Note the '&' after int in the function signature.
Also note that you use 'salary' in load() where it's not defined. You should use 'sal' instead.
That way the compiler knows that load() receives a reference to a variable, so if you modify it inside the function, the variable you sent to the function (salary) also changes.
The call itself to the function remains the same.