4

I've inherited some code which I'm going to be refactoring that makes extensive use of multiple variables at different scopes having the same name, ie:

int test = 456;
int main(void) {
    int test = 0;
    //...

    for (i=0; i<MAX_VAL; i++) {
        int test = 123;
        //...
    }
    return 0;
}

I know that if the same variable name is only used at two relevant levels of scope, I can access the globally accessible one by declaring extern int test within the deeper/lower levels of scope. With more than two levels though, I'm not sure which test variable is being accessed: the global scope variable or the variable at one scope level higher.

I've decided to re-write the code to use different variable names, and in doing so, have uncovered a lot of bugs that have been hard to track in the past. Is there a way to trigger a warning when such behavior is used? I have to compile the code in both Linux via GCC and Windows via Visual Studio 2010. If a portable approach isn't possible, is there a way for each of these compilers to warn about multiple variables at different scopes with the same name? This would let me build the code and have a list of all locations where such behavior is used.

Thank you.

Community
  • 1
  • 1
Cloud
  • 18,753
  • 15
  • 79
  • 153
  • If a variable shadows another, you cannot access that of the outer scope. Using an `extern` declaration has a different meaning and does not work for local or file-scope objects. (And it's a very dirty hack for global scope). So, I strongly support you refactoring such objects (and the original author should be punished with not less than 3 weeks. – too honest for this site Aug 27 '15 at 16:02
  • Are you flexible on Visual Studio version? VS 2015 reports `warning C4459: declaration of 'test' hides global declaration` and `warning C4456: declaration of 'test' hides previous local declaration` accompanied by `note: see declaration of 'test'` referencing previous declaration – Vlad Feinstein Aug 27 '15 at 16:07

2 Answers2

4

Both gcc and clang support the -Wshadow flag which warns about variables that shadow one another:

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

From Visual Studio 2015 you get a warning by default:

Shadowed variables

A variable declaration "shadows" another if the enclosing scope already contains a variable with the same name. For example:

void f(int x)
{
  int y;
  {
    char x; //C4457
    char y; //C4456
  }
}

The inner declaration of x shadows the parameter of function f, so the compiler will emit:

warning C4457: declaration of 'x' hides function parameter

The inner declaration of y shadows the declaration of y in the function scope, so the compiler will emit:

warning C4456: declaration of 'y' hides previous local declaration

Note that, as before, a variable declaration with the same name as a function parameter but not enclosed in an inner scope triggers an error instead:

 void f(int x)
 {
   char x; //C2082
 }

The compiler emits:

error C2082: redefinition of formal parameter 'x'

For older versions of Visual Studio you could enable Code Analysis (see How do I enable the 6000 series warnings (code analysis warnings) in MSVC++?) and take a look at warnings C6244 and C6246.

Community
  • 1
  • 1
manlio
  • 18,345
  • 14
  • 76
  • 126
3

With gcc you can use -Wshadow option to get a warning when a variable shadowds another variable of the same name. On MSVC there is apparently no similar option (on Visual Studio 2010 but as manlio added in his answer with Visual Studio 2015 they added a warning by default).

Community
  • 1
  • 1
ouah
  • 142,963
  • 15
  • 272
  • 331