1

Recently, I accidentally wrote C code that looks like this:

for (size_t i = 0; i < SOME_VALUE; ++i)
{
    for (size_t i = 0; i < ANOTHER_VALUE; ++i)
    {
        // do work with 'i' from inner loop *WITHOUT* any disruption to 'i' from outer loop
    }
}

Reading the code closely, I discovered this "bug". However, at runtime, it did not cause any issues. To be clear, my code was compiled with a relatively recent version of MinGW-w64 to create a native Win32 binary.

Sure, the code works, but I am surprised this is allowed, and even more surprised that my GCC-ish compiler did not complain about it! (Is there a GCC warning option for this mistake?)

Can someone explain why this is allowed, and why the inner and outer i variables do not conflict / disrupt? Ideally, someone can point me to official ISO-ish C language definition that allows (and supports) this behaviour!

Inspired by: What versions of C allow you to declare variables in for loops?

halfer
  • 19,824
  • 17
  • 99
  • 186
kevinarpe
  • 20,319
  • 26
  • 127
  • 154

1 Answers1

1

This is allowed, and is commonly referred to as shadowing, where the variable at the innermost scope shadows any variable with the same name at an outer scope.

This is explicitly allowed as specified in section 6.2.1p4 of the C standard regarding Scope of Identifiers:

... If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    It is called “hiding” in the C standard, not “shadowing”. There is no darkness (blocking of light) cast upon previous identifiers. Rather, they are not visible, hence hidden. – Eric Postpischil Mar 07 '22 at 17:25
  • 2
    *shadow* in common usage means the opposite of what you're saying in *the variable at the innermost scope shadows any variable with the same name*. It's typically used to mean a person or thing in another's shadow, not the one casting a shadow, e.g.: *the new guy is going to shadow you for the next few days to get up to speed.* – Caleb Mar 07 '22 at 17:33
  • 1
    The name of the gcc warning is `-Wshadow`. – ndim Mar 08 '22 at 15:24