Accessing variables in an enclosing scope(not global) hidden by local declaration in C++?

This is unfortunately not possible. Compiler warning options, like -Wshadow for GCC, can help avoiding such situations:

-Wshadow

Warn whenever a local variable or type declaration shadows another variable, parameter, type, class member (in C++), or instance variable (in Objective-C) or whenever a built-in function is shadowed. Note that in C++, the compiler warns if a local variable shadows an explicit typedef, but not if it shadows a struct/class/enum. Same as -Wshadow=global.

In your example, for instance, you'd get a warning like:

: In function 'int main()':

:7:9: error: declaration of 'i' shadows a previous local [-Werror=shadow]

7 |     int i = 5;

  |

As @L. F. points out in a comment below, you can use references to still have access to the other i:

#include <iostream>

int main() {
  int i = 10;
  if (1) {
    int& nonlocal_i = i; // just before shadowing
    int i = 5;
    std::cout << "Local i: " << i << std::endl;
    std::cout << "Main's i: " << nonlocal_i  << std::endl;
  }
  return 0;
}

But -Wshadow will still complain, and if you were going the extra mile to find an alternative name, you could just name the local i differently.


Note: As user4581301 points out in a comment, code like int& i = i; doesn't do what you'd expect in an inner scope:

#include <iostream>

int main()
{
    int i = 4;
    {
        int& i = i;
        std::cout << i;
    }
}

It tries to use the variable i to initialize itself. In Microsoft's compiler you get a compilation error like:

error C4700: uninitialized local variable 'i' used

In GCC, if you turn all the warnings on, you get this message:

error: reference 'i' is initialized with itself [-Werror=init-self]

But it silently compiles and does the wrong thing if you don't have the warnings turned on

Tags:

C++