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: clive@demon.net 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;