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: 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;