Point 1: You don't really have two x
s. The parameter is x
. The member x
's full name is abc::x
.
Point 2: The compiler is smart.
When he's the only John around, you can call John Smith John and those around you can usually figure out who you're referring to. In a room full of Johns, you might need to use his full name. In the event of multiple John Smiths, you may need to go a step further and use John Paul Smith.
In a large room you could get away with calling John Paul Smith John if the other Johns are further away. Everyone nearby will assume you are referring to the the closest John. If they are wrong, you, the communicator, would have to be more explicit.
The compiler's doing the same thing. The default behaviour is to use the closest x
, the one with the narrowest visible scope. That would be parameter x
. If you want to use an x
that is further away, you use an unambiguous name.
Notes:
While this case is easily avoidable and an easy source of bugs, making it a poor decision, you'll find you need to more fully qualify identifiers from time to time, for example when you want to call a member function of a base class from a derived class after the derived class has overridden the function.
Related, this is one of the reasons using namespace std;
is usually a bad idea.