ISO/ IEC JTC1/SC22/WG14 N712

                    Document Number:  WG14 N712/J11 97-075


                        C9X Revision Proposal
                        =====================

Title: Mix declarations and code
Author: Clive D.W. Feather
Author Affiliation: Demon Internet Ltd.
Postal Address: 322 Regents Park Road, London N3 2QQ, UK
E-mail Address: [email protected]
Telephone Number: +44 181 371 1138
Fax Number: +44 181 371 1037
Sponsor: BSI
Date: 1997-06-05
Proposal Category:
   __ Editorial change/non-normative contribution
   __ Correction
   XX New feature
   __ Addition to obsolescent feature list
   __ Addition to Future Directions
   __ Other (please specify)  ______________________________
Area of Standard Affected:
   __ Environment
   XX Language
   __ Preprocessor
   __ Library
      __ Macro/typedef/tag name
      __ Function
      __ Header
   __ Other (please specify)  ______________________________
Prior Art: Algol 68, C++
Target Audience: All programmers

Related Documents (if any): N503

Proposal Attached: Yes

Abstract:
C89 requires that all the declarations in a block preceed the first
statement in that block. There is no particular reason for this
restriction. This proposal allows arbitrary mixing of the two.

Notes:
This proposal was prepared with the assistance of Mark Brader, Jutta
Degener, Ron Guilmette, and a person whose employment conditions require
anonymity.


Proposal - Mix declarations and code
====================================

Summary
-------
C89 requires that all the declarations in a block preceed the first
statement in that block. There is no particular reason for this
restriction. This proposal allows arbitrary mixing of the two.

After consideration by WG14, it was requested that the proposal be
extended to include loop declarations compatible with C++, and other
control structures in a manner similar to C++. This revision adds these
features.

[N.B. I am not very familiar with C++. Thus there may be inadvertant
incompatibilites that will need to be fixed.]


Conformance
-----------
No C89 strictly-conforming program is affected by this proposal. All
programs that are newly strictly-conforming previously required a
diagnostic because they violated the syntax of subclause 6.6.2.


Discussion
----------
In the basic situation of declarations within a block, the only issue
that needs to be faced is that of jumping past declarations and
automatic variable initializations in either direction. In C89, it is
only possible to jump forward past one; it is now necessary to consider
what happens with a backward jump.

There are three options:
(1) Forbid labels before the last declaration in the block.
(2) Cause each initialization to be executed each time it is passed.
(3) Make the results undefined.

The first option, though superficially attractive, turns out to be
overly complex when the issues of nested blocks are considered. The last
seems to be too harsh; jumping around an initializer should be little
different from having the block in a loop. Therefore the second choice
has been used in this proposal.

The scope of variables appearing in declarations in each of the other
control structures is not necessarily obvious. I have decided to use a
strict textual point-of-view, treating the declaration as if it was
an expression evaluated at that point.


Detailed proposal
-----------------
In 6.1.2.4, third paragraph, replace:

    If an initialization is specified for the value stored in the
    object, it is performed on each normal entry, but not if the block
    is entered by a jump to a labelled statement.

with:

    If an initialization is specified for the value stored in the
    object, it is performed on each normal entry, but not if the block
    is entered by a jump to a labelled statement beyond the declaration.
    A backwards jump might cause the initializer to be evaluated more
    than once; if so, a new value will be stored each time.


Replace subclause 6.6.2 syntax by:

    compound-statement:
        { block-item-list-opt }

    block-item-list:
        block-item:
        block-item-list block-item

    block-item:
        declaration
        statement

Replace the last sentence of 6.6.2 semantics by:

    The initializers of objects that have automatic storage duration are
    evaluated, and the values stored in the objects (including storing
    an indeterminate value in objects without an initializer) each time
    that the declaration is reached in the order of execution, as if it
    were a statement, and within each declaration in the order that the
    declarators appear.

Replace 6.6.4 syntax by:

    selection-statement:
        if ( decl-expression ) statement
        if ( decl-expression ) statement else statement
        switch ( decl-expression ) statement

    decl-expression:
        expression
        declaration ; decl-expression

Append to 6.6.4 semantics:

    The statement:

        if (declaration-1; declaration-2; expression) statement

    and the compound-statement:

        { declaration-1; declaration-2; if (expression) statement }

    are equivalent, and similarly for the other two forms. [*1]

    [*1] Thus the scope of any identifier declared in the decl-expression
    consists of any later declarations, the expression, and the
    substatement.

Replace 6.6.5 syntax by:

    iteration-statement:
        while ( decl-expression ) statement
        do statement while ( decl-expression ) ;
        for ( expression-opt ; expression-opt ; expression-opt } statement
        for ( declaration    ; expression-opt ; expression-opt } statement

Replace 6.6.5.1 by:

    The evaluation of the controlling decl-expression takes place before
    each execution of the loop body. [*2]

    [*2] Thus the scope of any identifier declared in the decl-expression
    consists of any later declarations, the expression, and the
    substatement. Each such variable is created and initialized anew each
    time round the loop.

Replace 6.6.5.2 by:

    The evaluation of the controlling decl-expression takes place after
    each execution of the loop body. [*3]

    [*3] Thus the scope of any identifier declared in the decl-expression
    consists of any later declarations and the expression. Each such
    variable is created and initialized anew each time round the loop.

Replace 6.6.5.3 by:

    Except for the behaviour of a continue statement in the loop body,
    the statement

        for ( clause-1 ; expression-2 ; expression-3 ) statement

    and the block

        {
            clause-1 ;
            while ( expression-2 ) {
                statement
                expression-3 ;
            }
        }

    are equivalent. [94]

    Both clause-1 (which can be an expression or a declaration) and
    expression-3 can be omitted. The latter, and the former if it is an
    expression, is evaluated as a void expression. An omitted expression-2
    is replacd by a nonzero constant.

Add to footnote 94:

    If clause-1 is a declaration, then the scope of any variable it
    declares is the remainder of the declaration and the entire loop,
    including the controlling expression.

and change the first clause of the footnote to:

    Thus, clause-1 specifies initialization for the loop, possibly
    declaring one or more variables whose scope is specific to the loop;