Rule A2-10-1 (required, architecture / design / implementation, automated)

An identifier declared in an inner scope shall not hide an identifier declared in an outer scope.

Rationale

If an identifier is declared in an inner scope and it uses the same name as an identifier that already exists in an outer scope, then the innermost declaration will “hide” the outer one. This may lead to developer confusion. The terms outer and inner scope are defined as follows: Identifiers that have file scope can be considered as having the outermost scope. Identifiers that have block scope have a more inner scope. Successive, nested blocks, introduce more inner scopes.

Note that declaring identifiers in different named namespaces, classes, structs or enum classes will not hide other identifiers from outer scope, because they can be accessed using fully-qualified id.

Exception

An identifier declared within a namespace using the same name as an identifier of the containing namespace does not violate the rule. An identifier declared locally inside a lambda expression and not referring to a name of a captured variable does not violate the rule.

Example

//% $Id: A2-10-1.cpp 313834 2018-03-27 11:35:19Z michal.szczepankiewicz $
#include <cstdint>
std::int32_t sum = 0;
namespace
{
    std::int32_t sum; // Non-compliant, hides sum in outer scope
}
class C1
{
    std::int32_t sum; // Compliant, does not hide sum in outer scope
};
namespace n1
{
    std::int32_t sum; // Compliant, does not hide sum in outer scope
    namespace n2
    {
        std::int32_t sum; // Compliant, does not hide sum in outer scope
    }
}

std::int32_t idx;
void F1(std::int32_t idx)
{
    //Non-compliant, hides idx in outer scope
}

void F2()
{
    std::int32_t max = 5;

    for (std::int32_t idx = 0; idx < max; ++idx) // Non-compliant, hides idx in outer scope
    {
        for (std::int32_t idx = 0; idx < max; ++idx) // Non-compliant, hides idx in outer scope
        {
        }
    }

}
void F3()
{
    std::int32_t i = 0;
    std::int32_t j = 0;
    auto lambda = [i]() {
        std::int32_t j =
            10; // Compliant - j was not captured, so it does not hide
                // j in outer scope
        return i + j;
    };
}

See also

MISRA C++ 2008 [7]: required 2-10-2 Identifiers declared in an inner scope shall not hide an identifier declared in an outer scope.

JSF December 2005 [8]: 4.15 AV Rule 135 Identifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifier.

HIC++ v4.0 [9]: 3.1.1 Do not hide declarations.