Declarations/definitions as statements in C and C++

C++ allowed that the "substatement" of an iteration statement was implicitly a compound statement ([stmt.iter])

If the substatement in an iteration-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original statement. Example:

while (--x >= 0)
   int i;

can be equivalently rewritten as

while (--x >= 0) {
   int i;
}

the C standard does not have this language.

Additionally, the definition of a statement changed in C++ to include a declaration statement, so even if the above change wasn't made, it would still be legal.


The reason that adding braces makes it work is because your declaration now becomes a compound-statement which can include declarations.

You are allowed to have an identifier in a loop body without braces, so you can do this instead:

int a = 5;
for (int i = 0; i < 4; ++i)
    a;

In C++, a statement is (C++17 standard draft)

excerpt from [gram.stmt]

statement:
    labeled-statement
    attribute-specifier-seqopt expression-statement
    attribute-specifier-seqopt compound-statement
    attribute-specifier-seqopt selection-statement
    attribute-specifier-seqopt iteration-statement
    attribute-specifier-seqopt jump-statement
    declaration-statement
    attribute-specifier-seqopt try-block

init-statement:
    expression-statement
    simple-declaration

declaration-statement:
    block-declaration

...

Note that there are declaration statements in C++, which are declarations, and are statements. Similarly, simple declarations are init statements. Not all declarations are statements though. The grammar of declarations contains things that are not in the list of statements:

excerpt from [gram.dcl]

declaration:
    block-declaration
    nodeclspec-function-declaration
    function-definition
    template-declaration
    deduction-guide
    explicit-instantiation
    explicit-specialization
    linkage-specification
    namespace-definition
    empty-declaration
    attribute-declaration

block-declaration:
    simple-declaration
    asm-definition
    namespace-alias-definition
    using-declaration
    using-directive
    static_assert-declaration
    alias-declaration
    opaque-enum-declaration

simple-declaration:
    decl-specifier-seq init-declarator-listopt ;
    attribute-specifier-seq decl-specifier-seq init-declarator-list ;
    attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ] initializer ;

...

The list of declaration grammars continues on for a few pages.


In C, a statement is (C11 standard draft)

excerpt from Statements and blocks

statement:
    labeled-statement
    compound-statement
    expression-statement
    selection-statement
    iteration-statement
    jump-statement

Note that there are no declarations that are statements in C.


So, the meaning of statement is clearly different in the languages. Statement in C++ appears to have a broader meaning than statement in C.