redefinition of variable inside scope

2019-02-18 13:23发布

问题:

Why does the following code compiles, under g++, with out any warning or error? The problem I see is that the variable x defined in the first line is accessible inside the if scope but in spite that it's redefined again.

int main() {
    int x = 5;
    std::cout << x;
    if (true) {
        int x = 6;
        std::cout << x;
    }
}

回答1:

According to C-

6.2.1 in C99:

If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the } that closes the associated block

...

If an outer declaration of a lexically identical identifier exists in the same name space, it is hidden until the current scope terminates, after which it again becomes visible.

In both C and C++ it is legal for the same name to be used within multiple scopes.

So in your code the previous i remains hidden till the scope of if statement terminates.



回答2:

C++ standard allows name hiding, that means that you can declare anything with same identifier in nested scopes.

From N4296:

3.3.10 Name hiding [basic.scope.hiding]

  1. A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class.
  2. A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
  3. In a member function definition, the declaration of a name at block scope hides the declaration of a member of the class with the same name; see 3.3.7. The declaration of a member in a derived class (Clause 10) hides the declaration of a member of a base class of the same name; see 10.2.
  4. During the lookup of a name qualified by a namespace name, declarations that would otherwise be made visible by a using-directive can be hidden by declarations with the same name in the namespace containing the using-directive; see (3.4.3.2).
  5. If a name is in scope and is not hidden it is said to be visible

1 item of the list is what you need.



回答3:

The second x variable has a block scope and is shadowing the previous x declaration.



回答4:

The x you are using to print in the last line of your code, belongs to if block. This x hides the first x declared in first line. This is because the scope.

int main() {
    int x = 5;    //Accessble throughout the main.
    std::cout << x;
    if (true) {
        int x = 6;   //Local to this if block. Not accessible outside if block
        std::cout << x;   //Prints local x's value

    }
}