Just to clarify the situation: I can't imagine this ever changing in C++. To even hope to make it a tenable change, you'd have to tighten up type safety to the point that it would no longer be compatible with C (e.g., you'd pretty much have to eliminate all implicit conversions).
The situation is fairly simple: right now, name lookup stops at the first scope found that includes at least one instance of the name being used. If that instance of the name doesn't match the way you tried to use the name, then compilation fails.
Consider the obvious alternative: instead of stopping searching at that point, the compiler continues searching out scopes, created essentially an overload set of all those names, and then picked the one that matched the best.
In a case like this, a seemingly trivial change at an outer scope could (completely) change the meaning of some code, quite unintentionally. Consider something like this, for example:
int i;
int main() {
long i;
i = 1;
std::cout << i;
return 0;
}
Under the current rules, the meaning of this is clear and unequivocal: the i=1;
assigns the value 1 to the i
defined local to main
.
Under the revised rules, that would be open to question -- in fact, it probably shouldn't be the case. The compiler would find both instances of i
, and since 1
has type int
, it should probably be matched up with the global i
instead. When we print out i
, the compiler finds an overload that takes a long
, so it prints out the local i
(which still contains garbage).
Note that this adds another wrinkle though: the cout << i;
would be referring to the local i
because there was an overload that could work with it. So instead of the type of the variable controlling the overload that was used, you'd have the available overloads also controlling the variable that was used. I'm not sure, but I'd guess this makes parsing much more difficult (quite possibly an NP-hard or NP-complete problem).
In short, any code that (intentionally or otherwise) used almost any kind of implicit conversion at an inner scope, this seemingly unrelated changes at outer scopes could suddenly change the meaning of that code completely -- and as in the example above, easily break it quite thoroughly in the process.
In the case above, with only a half dozen lines of code, it's pretty easy to figure out what's going on. Consider, however, what happens when (for example) you define a class in a header, then include that header into some other file -- the compiler looks at the other code where you included the header, find a better match, and suddenly code you swore was thoroughly vetted and tested breaks most spectacularly.
With headers, it would (or at least could) get even worse though. You define your class, and include the header into two different files. One of those files defines a variable, function, etc. at outer scope and the other doesn't. Now code in one file using name X refers to the global, while code in the other file refers to the local, because the global doesn't happen to be visible in that file. This would completely break modularity, and render virtually all code completely broken (or at least breakable).
Of course, there would be other possibilities that might not be quite this broken. One possibility would be to eliminate all implicit conversions, so only a perfect type match would ever be considered. This would eliminate most of the obvious problems, but only at the expense of completely breaking compatibility with C (not to mention probably making a lot of programmers quite unhappy). Another possibility would be to search like it does now, stopping at the first scope where it found a match -- then continuing to outer scopes if and only if compilation was going to fail if it used that name at the inner scope.
Either of these could work, but (at the very least) you'd need quite a few restrictions to keep them from leading to almost insane levels of confusion. Just for example, consider something like a =1; a = '\2';
Right now, those must refer to the same variable -- but with the first of these rules, they wouldn't.
With some special cases, you could probably eliminate that particular oddity too -- for example, use the current rules for looking up variable names, and new/separate rules only for function names.
Summary: the simple/obvious way to do this would create a language that was almost irretrievably broken. Modifications to prevent that would be possible, but only at the expense of throwing away compatibility with both C and essentially all existing C++ code. The latter might be possible in a brand new language, but for a language that's already well established like C++ (especially on that became established largely based on backward compatibility -- C++ again).