As far as standards go, for
loop scopes are indeed defined differently in C and in C++. In C they are defined as follows:
6.8.5.3 The for statement
The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: ...
with no specific reference given to limitations on variable declarations inside the statement
. The top-level description of loops ("iteration statements" in the standard) specifies:
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.
as you've hinted in your question, code like:
for (int i = 0; i < 10; ++i)
int i = 5;
where a new block is not declared (notice the missing { }
surrounding the redeclaration) - is not valid code.
Whereas in C++, there is a specific reference to redeclaration of loop variables:
8.6 Iteration statements specify looping ... 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.
As it relates to rationale - likely C++ just added the restriction as an improvement to language semantics, indeed redeclaring a variable this way is usually a bug.
Arguably, this restriction is appropriate in C as well - but adding this restriction to the C standard would break backwards compatibility with existing code and is unlikely to happen.