Morpork
Morpork

Reputation: 551

C++ Redeclaring a variable in a sub-scope does not cause a compile error when it should?

I ran into a case where I had to swap out the value of a certain object. Due to my own sloppy copy and paste, I accidentally copied the type declaration as well. Here is a simplified example:

int main()
{
    int i = 42;
    cout << "i = " << i++ << endl;

    // ... much later

    if( isSwapRequired == true )
    {
        int i = 24;
        cout << "i = " << i++ << endl;
    }
    cout << "i = " << i++ << endl;
}

To my dismay, the compiler did not catch this and further went on to let i = 24 live in its own little scope. Then later, it turns out that outside the scope, i remains as 43. I noticed that if both i were in the same level, then the compiler would obligingly catch this mistake. Is there a reason for the compiler to treat the multiple declarations differently?

If it matters, I am using VS10.

Upvotes: 2

Views: 2134

Answers (2)

Alok Save
Alok Save

Reputation: 206566

This program is perfectly valid and correct as per rules laid out by the standard, the compiler does not need to catch anything, there is nothing to catch.

The standard allows same named variables to exist in their respective scopes and it clearly defines the rules as to which variable will be referenced when you use them in particular scope.Same named variables hide or shadow the variables at global scope.

Within in your local scope(within the conditional if block) the locally declared i hides the global i. If you need to access global i within this scope you need to use ::i.

Outside the conditional block, the only i that exists is the globally declared i.


Answer to question in comments:

Though compilers don't really have to warn of this, most compilers will provide you this diagnostic if you compile your program with highest warning level enabled or you explicitly tell the compiler to warn of this specific behavior.

For GCC, you can use -Wshadow.

-Wshadow

Warn whenever a local variable or type declaration shadows another variable, parameter, type, or class member (in 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.

Upvotes: 8

bash.d
bash.d

Reputation: 13207

This is no multiple declaration, because each of your is has a different scope and the local scope is always in favor of the global scope.

If you want to use your i from top-level of main() use ::i.

See here for a tutorial.

Upvotes: 1

Related Questions