Vamsi
Vamsi

Reputation: 87

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?

Upvotes: 0

Views: 189

Answers (5)

Thomas
Thomas

Reputation: 182000

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.

Upvotes: 2

Thomas
Thomas

Reputation: 182000

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 :)

Upvotes: 3

getdoo
getdoo

Reputation: 1

#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

Upvotes: -2

rootkonda
rootkonda

Reputation: 1743

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

Upvotes: 2

Creepsy
Creepsy

Reputation: 321

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/

Upvotes: 3

Related Questions