JTC1/SC22/WG14
N814
WG14/N814 J11/98-013
Subject: VLA's and decl/code mixing
From: Thomas MacDonald <tam@cray.com>
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.