Skip to content

CWG3221 [diff.stat] Add entry for C and C++ defining the scope of for loop identifiers differently #984

Description

@Halalaluyafail3

Full name of submitter (unless configured in github; will be published with the issue): Jay Ghiron

Reference (section label): [diff.stat]

Issue description:

See C DR 466:

        static inline int f (void) {
            for (int i = 0; ; ) {
                long i = 1;   // valid C, invalid C++
                // ...
                return i;     // (perhaps unexpectedly) returns 1 in C
            }
        }

In C2Y the same also applies to if and switch.

Partial suggested resolution:

Create a new paragraph at the end of [diff.stat]:

Affected subclause: [stmt.for]
Change: Names declared inside of the init-statement of a for loop have the same scope as names declared directly in the statement of the same for loop.
[Example 1:

for(int i=0;;){
  int i=1; // valid C, invalid in C++
  return i;
}

- end example]
Rationale: <to be decided>
Effect on original feature: Change to semantics of well-defined feature.
Difficulty of converting: Syntactic transformation. A second compound statement will allow reusing the name.
How widely used: Seldom.

Activity

  1. t3nsor commented on Aug 21, 2026

    @t3nsor

    That's not actually correct: [basic.scope.block] says that each iteration statement introduces a block scope, but the substatement also introduces a block scope. So there are two different scopes, but you're not allowed to declare an i in both of them because we have a special rule prohibiting it.

    I don't know the exact rationale, and a vague "catch some bugs" seems unconvincing to me. I've suggested in the past that we abolish all special rules of this kind.

  2. Halalaluyafail3 commented on Aug 22, 2026

    @Halalaluyafail3
    Author

    That's not actually correct: [basic.scope.block] says that each iteration statement introduces a block scope, but the substatement also introduces a block scope. So there are two different scopes, but you're not allowed to declare an i in both of them because we have a special rule prohibiting it.

    Perhaps a better way to describe it would be:

    Affected subclause: [stmt.for]
    Change: Names declared inside of the init-statement of a for loop cannot be hidden by the same names declared directly in the statement of the same for loop.
    [Example 1:

    for(int i=0;;){
      int i=1; // valid C, invalid in C++
      return i;
    }

    - end example]
    Rationale: <to be decided>
    Effect on original feature: Change to semantics of well-defined feature.
    Difficulty of converting: Syntactic transformation. A second compound statement will allow reusing the name.
    How widely used: Seldom.

  3. jensmaurer commented on Aug 23, 2026

    @jensmaurer
    Member

    CWG3221

    Removing the special-case rule is probably an EWG matter.

  4. changed the title [-][diff.stat] Add entry for C and C++ defining the scope of for loop identifiers differently[/-] [+]CWG3221 [diff.stat] Add entry for C and C++ defining the scope of for loop identifiers differently[/+] on Aug 23, 2026
  5. Halalaluyafail3 commented on Aug 27, 2026

    @Halalaluyafail3
    Author

    I believe the possessive form should be C++'s instead of C++', at least that is what the note in [basic.pre]/1 uses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions