In strictly conforming C 1990, declarations could appear only at file scope (outside of function definitions) or at the start of a compound statement. The grammar for a compound statement in C 1990 6.6.2 was:
compound-statement
{
declaration-listopt statement-listopt }
That says a compound statement is {
followed by zero or more declarations, then zero or more statements, then }
. So the declarations had to come first.
In C 1999 6.8.2, this changed to:
compound-statement
{
block-item-listopt }
A block-item-list is a list of block-item, each of which may be a declaration or a statement, so declarations and statements could be freely mixed.
In your example, the declarations int val = i + 1;
and int x = val * val;
do not appear after executable statements in their compound statement. The compound statement starts with the {
immediately before int val = i + 1;
, so that declaration is at the start of the compound statement.
Another change was that the for
grammar was changed from this in C 1990 6.6.5:
for
(
expressionopt ;
expressionopt ;
expressionopt )
statement
to this choice of two forms in C 1999 6.8.5:
for
(
expressionopt ;
expressionopt ;
expressionopt )
statement
for
(
declaration expressionopt ;
expressionopt )
statement
(Note the declaration includes a terminating ;
.)
That explains why you can have int i = 0
in for(int i = 0; i<=10; i++)
.