Public Comment Number PC-UK0077 ISO/IEC CD 9899 (SC22N2620) Public Comment =========================================== Date: 1998-03-09 Author: Clive D.W. Feather Author Affiliation: Self Postal Address: Demon Internet Limited 322 Regents Park Road London N3 2QQ United Kingdom E-mail Address: Telephone Number: +44 181 371 1138 Fax Number: +44 181 371 1037 Number of individual comments: 1 Comment 1. Category: Normative change to feature Committee Draft subsection: 6.1.2.4, 6.6.4.2, 6.6.6.1, 7.10.2.1 Title: Fix semantics of jumps in relation to VLAs NOTICE - this is a replacement for PC-UK0045, which is withdrawn. Detailed description: Consider the code: { int n = 1; label: int v [n]; /* ... */ if (n++ < 10) goto label; } The constraint on 6.6.6.1 does not forbid this jump, but the storage for v cannot be allocated on block entry as described in 6.1.2.4p3. Consider the code: { int n = 1; goto label; int v [n]; label: /* ... */ } This also does not violate the constraint, but the size of the array is never determined. Consider the code: int n; /* ... */ if (n > 0) goto label; { n = 1; label: int v [n]; /* ... */ } This is forbidden by 6.6.6.1, but its meaning is clear and sensible. The intent of the constraint in 6.6.6.1 is clearly to prevent a jump into a block from skipping a VLA declaration, but as can be seen it does not have this effect in practice. Similarly, the wording of 6.1.2.4p3 for VLAs is obviously an attempt to adapt the previous wording, but it does not have the right effect. Previous discussion within WG14 appeared to reach the conclusion that: - jumping into the scope of a VLA should violate a constraint; - jumping out of the scope of a VLA causes storage to no longer be reserved, even if the block containing the declaration has not been left; and these rules seem eminently practical. To do this: In 6.1.2.4p3, replace: Storage is guaranteed [...] execution of the block ends in any way. with: For objects that do not have a variable length array type, storage is guaranteed to be reserved for a new instance of such an object on each entry into the block with which it is associated; the object initially has indeterminate value. If an initialization is specified for the value stored in each object, it is performed each time the declaration is reached in the execution of the block; otherwise the value becomes indeterminate each time the declaration is reached. Storage for the object is no longer guaranteed to be reserved when execution of the block ends in any way. For objects that have a variable length array type, storage is guaranteed to be reserved for a new instance of such an object each time the declaration is reached in the execution of the program. The initial value is indeterminate. Storage for the object is no longer guaranteed to be reserved when execution of the program leaves the scope of the declaration [*]. [*] Leaving the innermost block containing the declaration, or jumping to a point in that block or an embedded block before the declaration, leaves the scope of the declaration. In 6.6.4.2p1, replace the first sentence with: The controlling expression of a /switch/ statement shall have integer type. If the /switch/ statement causes a jump to within the scope of an identifier with variably modified type, the entire /switch/ statement shall be within the scope of that identifier [*]. [*] That is, the declaration either preceeds the /switch/ statement, or it occurs after the last /case/ or /default/ label that is in the block containing the declaration and is associated with the /switch/. In 6.6.6.1p1, replace the second sentence with: A /goto/ statement shall not jump from outside the scope of an identifier with variably modified type to inside the scope of that identifier. In 7.10.2.1, change the last sentence of paragraph 2 from: If there has been no such invocation, or if the function containing the invocation of the /setjmp/ macro has terminated execution [192] in the interim, the behavior is undefined. to: If there has been no such invocation, or if the function containing the invocation of the /setjmp/ macro has terminated execution [192] in the interim, or if the invocation of the /setjmp/ macro was within the scope of an identifier with variably modified type and execution has left that scope in the interim, the behavior is undefined.