Search code examples
c++scopelanguage-lawyername-lookup

What the C++ standard exactly means by "same scope" in [basic.scope.hiding]?


In C++14 standard, [basic.scope.hiding], paragraph 2 (3.3.10.2), says:

A class name or enumeration name 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.

I'm disturbed by the wording "same scope". Indeed, in the following snippet of code, what are the cases where the class C and the variable C are declared in the same scope?

namespace case_1 {
    int C;
    class C;
    // Here C refers to variable
}

namespace case_2 {
    class C;

    namespace nested {
        int C;
        // Here C refers to variable
    }
}

namespace case_3 {
    int C;

    namespace nested {
        class C;
        // Here C refers to class
    }
}

namespace case_4 {
    enum Enum { A, B, C };
    class C;
    // Here C refers to enumerator
}

Hypothesis 1: "same scope" means "same block"

If we adhere to this hypothesis, the case 1 should be concerned by the rule 3.3.10.2. What about case 2? I guess it is covered by rule 3.3.10.1:

A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class.

Also, this hypothesis explains well the case 3 where the class name hides the variable name (and not the inverse) but can't explain the case 4. Indeed, C enumerator is declared in a different block than C class but the class is still hided.

Hypothesis 2: "declared in the same scope" means "have exactly the same scope"

If that hypothesis is true, no cases described in my code are concerned by the rule because it impossible for two name to have the exact same scope. Even the variable in case_1 has a different scope that the class. Indeed, the scope of the variable name starts after its declaration so before the class name.

Hypothesis 3: "declared in the same scope" means "one of the name is declared inside the scope of the other"

If this hypothesis is true, all the cases describe above should be covered by the rule 3.3.10.2. Indeed, in case_1 and case_3, C class is declared in the scope of C variable; in case_2, C variable is declared in the scope of C class; and, in case_4, C class is declared in the scope of C enumerator. However, the case_3 doesn't follow the rule because it is the variable who should "win" and stay visible.


As you can see, each of my hypothesis have a drawback and I really don't understand what the standard exactly means by "same scope" in that paragraph.


Solution

  • what are the cases where the class C and the variable C are declared in the same scope?

    Cases 1 and 4 are the same scope. Cases 2 and 3 are not the same scope.

    I cannot indeed find an accurate definition in the standard for "same" in this context, but the interpretation that makes sense, and matches the results of your test is to compare the smallest enclosing scope (or rather, declarative region1) of each declaration.

    Hypothesis 1: "same scope" means "same block"

    While a block has a scope, they are not equivalent. There are also namespace scopes and class scopes for example.

    but can't explain the case 4. Indeed, C enumerator is declared in a different block than C class but the class is still hided.

    Enumeration declarations don't have a scope. The enumerator and the class are in the same scope.

    Hypothesis 2: "declared in the same scope" means "have exactly the same scope"

    As you say, no declaration can have exactly the same scope with another, so this interpretation would make the rule meaningless.

    Hypothesis 3: "declared in the same scope" means "one of the name is declared inside the scope of the other"

    This is not correct interpretation in that a nested scope can be within the scope of one declaration, but it is not the same scope as far as the rule in question is concerned.


    1 In the latest standard draft, the wording has been changed to use the term "declarative region", which apparently has subtly different meaning than "scope". It doesn't change the intended meaning of the rule though.