Using a variable with the same name in different spaces - c++

This code compiles, but I have a run time error in Visual Studio:
Run-time check failure #3 - the variable 'x' is being used without being initialized...
int x = 15;
int main()
{
int x = x;
return 0;
}
I don't understand that behavior... in the error box when I click continue the program resumes and x has a corrupted content (like -8556328 instead of 15).
Why does this code work without a problem, and the int array is well declared?
const int x = 5;
int main()
{
int x[x] = {1,2,3,4};
return 0;
}

x is defined at the left of =.
so in x[x], [x] refer to the global one,
whereas in x = x;, x hides the global x and initializes from itself -> UB.

When you declare a new variable, its name becomes visible right here
int x =
// ^- there
because it is at that point the variable is fully declared, and as such; its name means something. At this point in time any other (previously declared variable) in a surrounding scope will be hidden.

There is no scope resolution operator in C, so you may not be able to use
int x = x;
in your program.

please use SRO( Scope resolution operator ::) to tell compiler which x is real x in your mind. As user defined names are mangled( Names are decorated) something like this to avoid ambiguity at it's level, these are just names used by compiler that best suits it
int x = 15;// Real name = gui_x
int main()
{
int x = x;// lui_x
return 0;
}
In this way run-time will know which version you are using but to avoid ambiguity it expects from you to use specific names. Sometimes above problem arise where you don't know that you are using already used names. For this C++ has created SRO.
Now in case of array x is address & not integer that stores something, that's why compiler didn't jumbled. You need to write
namespace abc //now all global variables are belongs to this ns abc
int x = 15;// Real name = gui_x
int main()
{
int x = abc::x;// lui_x
return 0;
}

Related

variable re-identification causing an infinite loop [duplicate]

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.

Why can't my function access and modify the variable passed to it?

i have written this little program to explain my point and my variable a remains unchanged it prints 4. I later learned that I need to use pointers or references; why is that?
#include <iostream>
void setToTen(int x) { x = 10; }
int main(){
int a = 4;
setToTen(a);
std::cout << a << std::endl;
}
In C++ arguments to functions are passed by value. This means that when you write
setToTen(a);
the parameter int x in setToTen is given a copy of the value stored in the variable a. In other words, you're not actually handing off the variable a into the setToTen function. Instead, you're giving a copy of that value to setToTen, so the changes made in that function affect the copy rather than the original.
On the other hand, if you change setToTen so that it takes its parameter by reference, like this:
void setToTen(int& x) {
x = 10;
}
the story is different. Here, calling setToTen(a) essentially hands the variable a into the function setToTen, rather than a copy of the value. That means that changes made to the parameter x in setToTen will change the variable a.
Your code requests a copy of x by having the signature void setToTen(int x).
Being able to take things by copy means that reasoning about the behavior of a function is far easier. This is true both for you, and for the compiler.
For example, imagine this:
int increase_some( int x, int y, int z ) {
for (int i = 0; i < y; ++i )
x+=z;
return x;
}
because x y and z are copies, you can reason about what this does. If they where references to the values "outside" of increase_some, the bit where you x+=z could change y or z and things could get crazy.
But because we know they are copies, we can say increase_some returns x if y<=0, and otherwise returns x+y*z.
Which means that the optimizer could change it to exactly that:
int increase_some( int x, int y, int z ) {
if (y<=0) return x;
return x + y*z;
}
and generate that output.
This is a toy example, but we took a complex function and turned it into a simple one. Real optimizers do this all the time with pieces of your complex function.
Going one step further, by taking things by immutable value, and never touching global state, we can treat your code as "functional", only depending on its arguments. Which means the compiler can take repeated calls to a function and reduce them to one call.
This is so valuable that compilers will transform code that doesn't have immutable copies of primitive data into code that does before trying to optimize -- this is known as static single assignment form.
In theory, a complex program with lots of functions taking things by reference could be optimized this same way, and nothing be lost. But in practice that gets hard, and it is really easy to accidentally screw it up.
That is the other side; making it easier to reason about by people.
And all you have to embrace is the idea of taking arguments by value.
Function parameters are function local variables that are not alive after exiting function.
You can imagine the function definition and its call
int a = 4;
setToTen(a);
//...
void setToTen(int x) { x = 10; }
the following way
int a = 4;
setToTen(a);
//...
void setToTen( /* int x */ ) { int x = a; x = 10; }
As it is seen within the function there is declared a local variable x which is initialized by the argument a. Any changes of the local variable x do not influence on the original argument a.
If you want to change the original variable itself you should pass it by reference that is the function will deal with a reference to the variable. For example
void setToTen(int &x) { x = 10; }
In this case you can imagine the function definition and its call the following way
int a = 4;
setToTen(a);
//...
void setToTen( /* int x */ ) { int &x = a; x = 10; }
As you see the reference x is as usual local. But it references the original argument a. In this case the argument will be changed through the local reference.
Another way is to declare the parameter as pointer. For example
void setToTen(int *x) { *x = 10; }
In this case you have to pass the original argument indirectly by its address.
int a = 4;
setToTen( &a );

How is it possible to have two variables with same names - one is global and another one is local? [duplicate]

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.

Static scoping in C/C++

In the following code, 2 is printed.
int x = 1;
int f(int y)
{
return x;
}
int main() {
x = 2;
printf("%d", f(0));
}
How is it happening if we have static scoping in C? Why isn't 1 printed?
Printing 2 in this case isn't a dynamic scoping, is it?
I thought that in static scoping it should take the nearest x to the function definition.
It does take the nearest x, but since you only have one x it doesn't really matter.
If you change the code to
int x = 1;
int f(int y)
{
return x ;
}
int main() {
int x=2;
printf("%d", f(0));
}
so you have 2 x, the global one and the local one in main you will see 1 getting printed.
Those are usually called dynamic and lexical scoping.
Lexical scoping is determined entirely at compile time, dynamic scoping at runtime.
You only have one variable named "x", so scope is irrelevant to your program.
Here's a program that would be different depending on the scoping rules:
int x = 0;
int f()
{
return x;
}
int main()
{
int x = 1;
printf("%d\n", f(x));
}
Under lexical scoping, f returns the value of the x that is lexically "nearest" - the global one.
So it would print 0;
Under dynamic scoping, f would return the value of the newest x, which is the one in main.
So it would print 1.
The scoping is moot here since you have not declared an x locally that would have otherwise shadowed the global x.
2 is printed.
x is assigned in main to 2 immediately before f is called with the parameter 0.
(Conceptually int x = 1; is ran before main is entered.)
It is the way the compiler generates the assembly/machine code.
first global variable X is stored in memory location "abc"
next main is executed: global variable X at "abc" is changed to 2
Now function f() is called:
function f returns the value of global variable X at "abc": being 2
the return value of f() is printed.
So if you wanted a different X in the main-function scope, you should have made a new object, like in the answer by nwp.

how to access a specific scope in c++?

#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.