Question: This code illustrates something that I think should be treated as bad practice, and elicit warnings from a compiler about redefining or masking a variable:

```
#include <iostream>

int *a;

int* f()
{
  int *a = new int;
  return a;
}

int main()
{
  std::cout << a << std::endl << f() << std::endl;
  return 0;
}

```

Its output (compiled with g++):

```
0
0x602010

```

I've looked at a couple references (Stroustrup and The Complete C++ Reference) and can't find anything about when and why this is allowed. I know that it's not within a single local scope, though.

When and why is this allowed? Is there a good use for this construct? How can I get g++ to warn me about it? Do other compilers squawk about it?

Answer: 
A lot of languages allow this sort of thing.  

Usually (in relation to all languages) the most locally defined variable is the one you are referring too. Of the 20+ languages I have used this is very common.

Also most languages allow you to explicitly refer to the one in the outer scope.  

For example C++ alows you to specify the variable in global scope with the :: operator.

```
#include  <iostream>

int a = 5;
int main()
{
    int a = 6;

    std::cout << a << "\n" << ::a << "\n";
            // Local
                           // global
}

```
To answer when this is allowed: basically in any two nested scopes.

For instance:

```
void foo() {
    int a;
    {
        int a;
    }
}

class Base {
    int a;
};
class Derived: public Base {
    int a; // Yes, the name Base::a is visible in the scope of Derived, even if private
};

class Foo() {
    int a;
    Foo(int a) : a(a) { } // Works OK
};

using std::swap;
void swap(MyClass& lhs, MyClass& rhs);
// Not strictly a variable, but name lookup in C++ happens before determining 
// what the name means.

```

Now, the answer must clearly be that having two 'things' with a single name in the same scope is generally allowed. This is possible because at most one of the names is actually *defined* in that scope; others would be merely *visible* in that scope. Name resolution rules determine which name is chosen, if there are multiple candidates. 

You really do not want to give a warning for every case where the compiler picks between alternatives. That will give you tons of warnigns, on such innocent things as overloading and some smart template code.