WG14/N814 J11/98-013 Subject: VLA's and decl/code mixing From: Thomas MacDonald Date: Mon, 27 Oct 1997 Douglas Walls writes: > Tom and Clive, > > I am a tad bit confused as to the outcome of how VLA's and the mixing > of code with declarations has turned out following last weeks WG14 > meeting. I don't mean to burden either of you with any work, however I > am sure that I and the rest of those on the WG14 alias would benifit > from a summary of how VLA's work when mixed with code. > > Regards, Douglas I talked to Rex about this privately at the meeting. I told him that this is an area where the C Standard is broken. Rex suggested that we handle this during public comment. At the moment, mixed code and decls is broken cause it doesn't take into account a VLA involving a branch. There are 2 issues: 1. Branching and skipping a VLA Decl This should be a constraint along the lines of the current wording in 6.1.2.4 --- If the block with which the object is associated is entered by a jump from outside the block to a labeled statement in the block or in an enclosed block, then storage is guaranteed to be reserved provided the object does not have a variable length array type. If the object is variably modified and the block is entered by a jump to a labeled statement, then the behavior is undefined. 2. Branching Backwards before a VLA Basically, if branch from a point where a VLA is in scope to a label where that VLA is out of scope, then what happens? Several of us have proposed the C++ constructor/destructor model. The committee has never voted on this cause there was no agenda time in Menlo Park. I've identified several places in the Draft where this is an issue: I've identified several places in the Draft where there are problems: 6.1.2.4 doesn't specify what to do when a VLA is encountered via a backwards jump: A backwards jump might cause the initializer to be evaluated more than once; if so, a new value will be stored each time. I love that word "might" in this sentence because it implies that the implementation _might not_ evaluate the initializer more than once. This needs better specification. It also doesn't say that a VLA size expression might be evaluated more than once. Seems like a forward jump can also cause an initializer to be evaluated more than once too. - 2 - What about typdef names? { int n = 100; typedef int A[n]; L: n++; A a; if (n < 1000) goto L; Is the size expression for "a" reevaluated every time the definition of "a" is encoutered? Need better specification of this. 6.5.7 Type definitions [#3] Any array size expressions associated with variable length array declarators shall be evaluated with the typedef name at the beginning of its scope upon each normal entry to the block. What if there is a goto to a label before the typdef declarator? That's not a normal entry to the block, so the VLA size expression is not evaluated. Need better specification. 6.6.4.2 The switch statement Constraints [#1] The controlling expression of a switch statement shall have integral type, and shall not cause a block to be entered by a jump from outside the block to a statement that follows a case or default label in the block (or an enclosed block) if that block contains the declaration of a variably modified object or variably modified typedef name. The What happens if the VLA declaration comes after the label: if (n > 0) switch(n) { case 1: { ... break; } case 2: case 3: int a[n]; ...... break; } The constriant above makes this an error but it seems like it's in the spirit of mixed code & decls. Need better specifiation. Also, I'm not sure how mixed code & decls behaves with setjmp/longjmp. This is currently a major issue that is not resolved by the current Draft.