accessing variables from an intended block of nested blocks [duplicate] - c++

This question already has answers here:
Is there any way to access a local variable in outer scope in C++?
(4 answers)
Closed 5 years ago.
In the program below, how to retrieve value of aa from Block A in Block C?
We can only access the outermost global aa using scope resolution operator.
Known solutoins:
1. Use different pointers in different blocks
2. Use the variable in parent block before using the current block's variable
I am looking for any other alternative solution
I know that this is not good code. Just curious in understanding how to achieve it.
#include <iostream>
#include <cstdio>
using namespace std;
// Global
int aa = 10;
int main()
{
// Main
int aa = 20;
{
// Block A
int aa = 30;
{
// Block B
int aa = 40;
{
// Block C
int aa = 50;
cout << "block C " << aa << endl;
cout << "block A " << ????? << endl;
cout << "global" << ::aa << endl;
}
cout << "block B " << aa << endl;
}
cout << "block A " << aa << endl;
}
cout << "main " << aa << endl;
return 0;
}

I know that this is not good code. Just curious in understanding how to achieve it.
You can't.
Undecorated use of the variable aa will use the one that is in the nearest scope.
Decorated use of the variable, ::aa, will use the one that is in the scope outside the function.
Decorated use of the variable, <NS>::aa, will use the one that is in the scope of the namespace <NS>.

Use references.
// Block A
int aa = 30;
auto& ref_aa = aa;
{
// Block B
int aa = 40;
{
// Block C
int aa = 50;
cout << "block C " << aa << endl;
cout << "block A " << ref_aa << endl;
cout << "global" << ::aa << endl;
}
cout << "block B " << aa << endl;
}
Of course, that's quite meaningless; if you can modify the code, then just change the variable names, or refactor it such that fewer blocks are needed (using more functions, for example).

Related

question on c++ object construction and scope

this is a little bit difficult to put into words, here is the snippet,
int main() {
int i = 5;
{
int i(i);
i = i+5;
// int i = i;
// i = i + 5;
cout << "inner scope" << endl;
cout << i << endl;
}
cout << "outer scope" << endl;
cout << i << endl;
}
this give the correct output
inner scope
10
outer scope
5
But if I do this,
int main() {
int i = 5;
{
//int i(i);
//i = i+5;
int i = i;
i = i + 5;
cout << "inner scope" << endl;
cout << i << endl;
}
cout << "outer scope" << endl;
cout << i << endl;
}
This throws an runtime exception, and gives wrong output,
inner scope
-858993455
outer scope
5
I feel this seems to be jsomething to do with the difference in the sequence of calling of copy constructor and assignment constructor, but I am not entirely sure, please enlighten me.
When you shadow a variable you remove all trace of it within that scope, so:
int i = i;
This declares i to equal its (uninitialized) self. This variable is completely independent from the parent scope's i. This is effectively undefined behaviour.
Curiously the int i(i) approach uses the parent scope's i to initialize, though that's rather peculiar that it works out. It might not be defined behaviour though.
You should be using a different variable name if you need to relate these two somehow. You can shadow if there's no inter-dependency.
In other words:
int j = i;

Difference in the usage of function prototype with / without pointers

I'm following simple C++ tutorial.
#include <iostream>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "Before swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a,b);
cout << endl;
cout << "After swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int &n1, int &n2)
{
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
The above code works fine (both g++ and icc), but if I were to use pointers in the functions the code fails if I do not include the prototype at the head of the program.
#include <iostream>
using namespace std;
void swap(int*, int*); // The code fails if I comment this line.
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
As far as I know, C++ compiling process is top-bottom, so the 2nd code seems more reasonable in which the information of the function is provided before int main() is encountered. My question is, why the 1st code works fine even without the knowledge of function before int main()?
The issue with the first program is you're not actually calling your own swap function. At the top of the file, you have:
using namespace std;
which brings std::swap into scope and that's the function that you're actually calling. If you put a cout statement in your own swap you'll see that it's never actually called. Alternatively, if you declare your swap before main, you'll get an ambiguous call.
Note that this code is not required to behave like this, since iostream doesn't necessarily bring std::swap into scope, in which case you'll get the error that there is no swap to call.
In the second program, the call to swap(&a, &b) fails because there is no overload of std::swap that accepts 2 temporary pointers. If you declare your swap function before the call in main, then it calls your own function.
The real bug in your code is the using namespace std;. Never do that and you'll avoid issues of this nature.
The reason why the first version works is because it doesn't call your swap(...) function at all. The namespace std provides - Edit: depending on the headers you (and the standard headers themselves) include - swap(...) functions for various types and integers are one of them. If you would remove using namespace std you would have to type std::swap(...) to achieve the same effect (same goes for std::cout, std::endl).
That's one reason why using namespace is a double-edged sword for beginners in my opinion but that's another topic.
Your code is fine; but you're right, it fails if you comment on the line you point to.
But actually, as the others tell you, there is a Swap function in c ++, so it doesn't matter if you create a prototype of the function and do it later because the compiler calls its own swap function.
But since swap works for any data type, except for pointers, then you will understand the reason for your problem, since in this case you do have to create your own swap function that accepts pointers as parameters.
Just move your function above main to make it work correctly, nothing more:
#include <iostream>
using namespace std;
//void swap(int*, int*); // The code fails if I comment this line.
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}

C++ How would the calling of these functions change if i change the parameter argument from an int* to int [duplicate]

This question already has an answer here:
C++ parameter passing queries (code examples and outputs included)
(1 answer)
Closed 8 years ago.
First of all, i have no idea how to word the title whilst keeping it descriptive if anybody has a better idea feel free to edit.
My question is as follows; I have been given a set of function definitions and calls to these functions which currently operate using an int* as the variable that is being passed in various ways to these functions.
My task is to without changing the function definitions make the program compile and produce the same output but this time use an int over an int*.
Desired output:
Result
first 43
second 43
third 44
fourth 0
fifth 69
This is the code for the when the variable is an int*
void MyIncrementFirst(int* i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int** i) {
*i = new int(0);
}
void MyIncrementFifth(int*& i) {
i = new int(69);
}
int main(){
int* a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " <<*a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
return 0;
}
Now here is what i have so far when changing the type of a to an int, not an int*:
Note: The function definitions are the same as above.
int main(){
int a = 42;
cout << "Result" << endl;
MyIncrementFirst(&a);
cout << "first " <<a << endl;
MyIncrementSecond(a);
cout << "second " <<a << endl;
MyIncrementThird(a);
cout << "third " <<a << endl;
/*
MyIncrementFourth(&a);
cout << "fourth " <<a << endl;
MyIncrementFifth(a);
cout << "fifth " <<a << endl;
*/
return 0;
}
Which prints:
Result
first 43
second 43
third 44
Calls to MyIncrementFourth and MyIncrementFith have been commented because i am not sure how to translate this to handle an int rather than an int*. Any attempts i do would just be fluke rather than knowledge.
Can anybody help me identify how to correctly complete the calls to MyIncrementFourth and MyIncrementFith in order to achieve a correct result.
Thanks,
Chris.
void foo(int a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
While with * it would be like this
void foo(int* a) {
...
}
int main() {
int a = 5;
foo(&a);
return 0;
}
However, this reminds of C.
You could use the & operator, instead of the *, like this:
void foo(int& a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
I assume you know what passing by value and by reference means. If you want a refresh, take a look in my example here.
[EDIT]
Also note that the code in the first block of yours is not OK, since you call new twice, but you never call delete.
Also, about what you are asking, you cannot do it without using an extra pointer. In other words, it can not be done by only having int a in the play.
Example:
int* a_pointer = &a;
MyIncrementFourth(&a_pointer);
cout << "fourth " << a << ", but a_pointer points to " << *a_pointer << endl;
Why the value of a did not change, despite the fact that we set the a_pointer to be equal with the address of a.
Because inside your function, you are calling new and as you know, it will return a pointer to the new allocated memory.
As a result, a_pointer is assigned a new value. Which value? The address of the new allocated memory.
When you use
int a = 42;
instead of
int* a = new int(42);
fourth and fifth function can't be used. The MyIncrementFourth and MyIncrementFifth (counterintuitive names, by the way) pretend to replace the pointer you allocated in the main with another pointer to another area, allocated inside the functions (and there will be a memory leak since you no longer will be able to delete the original a…). But if you stick to int a = 42 instead of int* a = new int(42), your variable is not a pointer, thus those functions have no pointer they can replace.
You can use:
int* ap = &a;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
// It does not change the value a.
You can also use:
int* ap = NULL;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
int* ptr;
MyIncrementFourth(&ptr);
a = *ptr;
delete ptr;
std::cout << "fourth " << a << std::endl;
MyIncrementFifth(ptr);
a = *ptr;
delete ptr;
std::cout << "fifth " << a << std::endl;

How to access a local area variable at the other local area? [duplicate]

This question already has answers here:
Accessing variables with the same name at different scopes [duplicate]
(2 answers)
Closed 8 years ago.
I'm recently studying C++ language.
I have been wondered how to access local variable "a" of local area[1] at local area[2] watching the follow code.
How to do that?
#include "stdafx.h"
using namespace std;
///// global area /////
int a = 1;
int _tmain(int argc, _TCHAR* argv[])
{
///// local area[1] /////
int a = 2; //<= how to access this "a" at local area[2]?
cout << "global area [a] : " << ::a << endl;
cout << "local area[1] [a] : " << a << endl;
{
///// local area[2] /////
int a = 3;
cout << "global area [a] : " << ::a << endl;
cout << "local area[2] [a] : " << a << endl;
cout << "local area[1] [a] : " << ?????? << endl;
}
return 0;
}
You can't do this. When you declare a variable in the inner scope, it shadows the outer scope's variable and the language doesn't provide any way to access it like it does for global variables.
Even if it did support this however, it would still be bad practice to name your variables the same. Imagine having to handle a large number of scopes and the complexity that would be required!
Simply use different variable names for intermediate variables, it makes both writing and maintaining the code easier.
You need a bit of help from the outer scope:
using std::cout;
using std::endl;
int main(int argc, char* argv[])
{
///// local area[1] /////
int a = 2; //<= how to access this "a" at local area[2]?
int& alternative_name = a;
cout << "global area [a] : " << ::a << endl;
cout << "local area[1] [a] : " << a << endl;
{
///// local area[2] /////
int a = 3;
cout << "global area [a] : " << ::a << endl;
cout << "local area[2] [a] : " << a << endl;
cout << "local area[1] [a] : " << alternative_name << endl;
}
return 0;
}

Is there any way to access a local variable in outer scope in C++?

Just out of curiosity: if I have nested scopes, like in this sample C++ code
using namespace std;
int v = 1; // global
int main (void)
{
int v = 2; // local
{
int v = 3; // within subscope
cout << "subscope: " << v << endl;
// cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
}
cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
}
Is there any way to access the variable v with the value 2 from the "intermediate" scope (neither global nor local)?
You can declare a new reference as an alias like so
int main (void)
{
int v = 2; // local
int &vlocal = v;
{
int v = 3; // within subscope
cout << "local: " << vlocal << endl;
}
}
But I would avoid this practice this altogether. I have spent hours debugging such a construct because a variable was displayed in debugger as changed because of scope and I couldn't figure out how it got changed.
The answer is No You cannot.
A variable in local scope shadows the variable in global scope and the language provides a way for accessing the global variable by using qualified names of the global like you did. But C++ as an language does not provide anyway to access the intermediate scoped variable.
Considering it would have to be allowed it would require a lot of complex handling, Imagine of the situation with n number of scopes(could very well be infinite) and handling of those.
You are better off renaming your intermediate variables and using those that would be more logical and easy to maintain.
There are two types of scope resolution operators in C++ - unary scope and a class scope. There is no function scope or "any particular parent scope" resolution operators. That makes it impossible to solve your problem, as it is, in general because you cannot refer to anonymous scopes. However, you can either create an alias, rename variables, or make this a part of the class, which of course implies a code change. This is the closest I can get you without renaming in this particular case:
#include <iostream>
using namespace std;
int v = 1; // global
class Program
{
static int v; // local
public:
static int main ()
{
int v = 3; // within subscope
cout << "subscope: " << v << endl;
cout << "local: " << Program::v << endl;
cout << "global: " << ::v << endl;
}
};
int Program::v = 2;
int main ()
{
return Program::main ();
}
There are other ways, like making sure that variables are not optimized out and are on stack, then you can work with stack directly to get the value of the variable you want, but let's not go that way.
Hope it helps!
You could fake it like this:
#include <iostream>
using namespace std;
int v = 1;
int main()
{
int v = 2;
{
int &rv = v; // create a reference
int v = 3; // then shadow it
cout << "subscope: " << v << endl;
cout << "local: " << rv << endl;
cout << "global: " << ::v << endl;
}
cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
return 0;
}
Interestingly this compiles on cygwin g++ but segfaults if you try to run it:
#include <iostream>
using namespace std;
int v = 1;
int main()
{
int v = 2;
{
int &v = v;
cout << "subscope: " << v << endl;
// cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
}
cout << "local: " << v << endl;
cout << "global: " << ::v << endl;
return 0;
}