Why doesn't the C compiler give a redeclaration error inside a for loop body? [duplicate]

  • A+
Category:Languages

This question already has an answer here:

In the C language, if we write this:

for(int i = 0; i < 7; i++) {     // for loop Body } 

The scope of variable i is inside the for loop body. It is OK.

But, if I write this:

for(int i = 0; i < 7; i++) {     long int i = 1; // Redeclaration of i } 

Here, the variable i is declared again inside the loop body, yet it successfully compiles and runs in C.

But, in C++, the compiler gives a "redeclaration of 'long int i'" error.

So, why doesn't the C compiler give a redeclaration error? Is it a compiler bug?

 


C++ and C make a distinction here. According to C11 (n1570) §6.8.5 ¶5, emphasis mine:

An iteration statement is a block whose scope is a strict subset of the scope of its enclosing block. The loop body is also a block whose scope is a strict subset of the scope of the iteration statement.

Which translates to this for a for loop:

{     declaration      while ( expression) {         statement         expression ;     } } 

Anything you put in the statement part can hide whatever is introduced in the declaration. Now, C++(17, n4659) explicitly says something similar at [stmt.for]/1. But it also goes on to add:

except that names declared in the init-statement are in the same declarative region as those declared in the condition,

So here the second i is indeed an attempt at a re-declaration. The above may sound confusing (names declared in the condidion!?), but the "condition" here is defined like this ([stmt.stmt]/1):

condition:     expression     attribute-specifier-seq decl-specifier-seq declarator brace-or-equal-initializer 

It's that which allows while loops like this (C++ only):

while (T t = x) statement  

And you may not re-declare t inside the statement of the while loop.


Alternatively, the entire conclusion I reach is summarized in [stmt.iter]/3 (thank you @T.C.):

If a name introduced in an init-statement or for-range-declaration is redeclared in the outermost block of the substatement, the program is ill-formed.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: