WG14/N683 (J11/97-046) WG14/N683 (J11/97-046) Final Edits for incorporating VLAs into C9X Tom MacDonald tam@cray.com 655F Lone Oak Road Eagan MN 55121 USA 08-May-1997 The following edits are against version C9XD9-pre3. Quoted text (e.g., "sizeof") implies bold-courier font. %% %% Change #1 %% 6.1.2.4 Storage duration of objects [#3] An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration. Storage is guaranteed to be reserved for a new instance of such an object on each normal entry into the block with which it is associated End the sentence in C9XD9-pre3 here, and replace its final clause: , or on a jump from outside the block to a labeled statement in the block or in an enclosed block. With: . 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. End of change. %% %% Change #2 %% Add the following forward references to 6.1.2.4 variably modified (6.5.4), variable length array (6.5.4.2). End of change. %% %% Change #3 %% 6.1.2.6 Compatible type and composite type [#3] A composite type can be constructed from two types that are compatible; it is a type that is compatible with both of the two types and satisfies the following conditions: Replace the following words in C9XD9-pre3: - If one type is an array of known size, the composite type is an array of that size. With: - If one type is an array of known constant size, the composite type is an array of that size; otherwise, if one type is a variable length array the composite type is that type. End of change. %% %% Change #4 %% 6.3 Expressions 6.3.3.4 The "sizeof" operator Semantics [#2] The "sizeof" operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. Replace the following words in C9XD9-pre3: The size is determined from the type of the operand, which is not itself evaluated. The result is an integer constant. With: The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant. End of change. %% %% Change #5 %% Add the following example to 6.3.3.4: int fsize3(int n) { char b[n+3]; /* variable length array */ return sizeof b; /* execution time sizeof */ } main() { int size; size = fsize3(10); /* func returns the value 13 */ } End of change. %% %% Change #6 %% Add the following forward reference to 6.3.3.4 variable length array (6.5.4.2). End of change. %% %% Change #7 %% Add the following example to 6.3.6 Additive operators: Pointer arithmetic is well defined with pointers to variable length array types. { int n = 4, m = 3; int a[n][m]; int (*p)[m] = a; /* p == &a[0] */ p += 1; /* p == &a[1] */ (*p)[2] = 99; /* a[1][2] == 99 */ n = p - a; /* n == 1 */ } If array "a" in the above example is declared to be an array of known constant size, and pointer "p" is declared to be a pointer to an array of the same known constant size that points to "a", the results are still the same. End of change. %% %% Change #8 %% 6.4 Constant expressions [#6] An integral constant expression shall have integral type and shall only have operands that are integer constants, enumeration constants, character constants, "sizeof" expressions Add the following words to paragraph 6 above: whose operand does not have variable length array type or a parenthesized name of such a type, End of change. %% %% Change #9 %% Add the following forward reference to 6.4 variable length array (6.5.4.2). End of change. %% %% Change #10 %% 6.5 Declarations 6.5.2 Type specifiers Add the following as a new paragraph to the end of the Constraints: Only ordinary identifiers (as defined in 6.1.2.3) with block scope or function prototype scope and without linkage can have a variably modified type. If an identifier is declared to be an object with static storage duration, it shall not have a variable length array type. End of change. %% %% Change #11 %% Add the following example to 6.5.2 Type specifiers: All declarations of variably modified (VM) types must be declared at either block scope or function prototype scope. Array objects declared with the "static" or "extern" storage class specifier cannot have a variable length array (VLA) type. However, a object declared with the "static" storage class specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a VM type must be ordinary identifiers, and can not, therefore, be members of structures or unions. extern int n; int A[n]; /* Error - file scope VLA */ extern int (*p2)[n]; /* Error - file scope VM */ int B[100]; /* OK - file scope but not VM */ void fvla(int m, int C[m][m]) { /* OK - VLA with prototype scope */ typedef int VLA[m][m]; /* OK - block scope typedef VLA */ /* array size m evaluated now */ struct tag { int (*y)[n]; /* Error - y is not an ordinary identifier */ int z[n]; /* Error - z is not an ordinary identifier */ }; int D[m]; /* OK - auto VLA */ static int E[m]; /* Error - static block scope VLA */ extern int F[m]; /* Error - F has linkage and is a VLA */ int (*s)[m]; /* OK - auto pointer to VLA */ extern int (*r)[m]; /*Error - r has linkage and is a pointer to VLA*/ static int (*q)[m] = &B; /* OK - q is a static block scope VM */ /* ... */ } End of change. %% %% Change #12 %% Add the following forward references to 6.5.2 variably modified (6.5.4), variable length array (6.5.4.2). End of change. %% %% Change #13 %% 6.5.2.1 Structure and union specifiers [#7] A member of a structure or union may have any object type Add the following words to paragraph 7 above: other than a variably modified type. *Footnote ____________________ * A structure or union can not contain a member with a variably modified type bacause member names are not ordinary identifiers as defined in 6.1.2.3 End of change. %% %% Change #14 %% 6.5.4 Declarators [#2] Each declarator declares one identifier, and asserts that when an operand of the same form as the declarator appears in an expression, it designates a function or object with the scope, storage duration, and type indicated by the declaration specifiers. Add the following paragraph after paragraph 2 above: A `full declarator' is a declarator that is not part of another declarator. The end of a full declarator is a sequence point. If the nested sequence of declarators in a full declarator contains a variable length array type, the type specified by the full declarator is said to be "variably modified." End of change. %% %% Change #15 %% Add the following forward reference to 6.5.4 variable length array (6.5.4.2). End of change. %% %% Change 16 %% 6.5.4.2 Array Declarators Constraints Replace the following words in C9XD9-pre3: [#1] The expression delimited by [ and ] (which specifies the size of an array) shall be an integral constant expression that has a value greater than zero. With: The [ and ] may delimit an expression or *. If [ and ] delimit an expression (which specifies the size of an array), it shall have an integral type. If the expression is a constant expression then it shall have a value greater than zero. End of change. %% %% Change 17 %% Semantics [#2] If, in the declaration ``T D1,'' D1 has the form Replace the following words in C9XD9-pre3: D[ constant-expr ] opt With: D[ assignment-expression ] opt or D[*] End of change. %% %% Change 18 %% and the type specified for ident in the declaration ``T D'' is ``derived-declarator-type-list T,'' then the type specified for ident is ``derived-declarator-type-list array of T.'' If the size is not present, the array type is an incomplete type. Add the following words to paragraph 2 above: If * is used instead of a size expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope. If the size expression is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type. Otherwise, the array type is a variable length array type. If the size expression is not a constant expression, and it is evaluated at program execution time, it shall evaluate to a value greater than zero. It is unspecified whether side effects are produced when the size expression is evaluated. The size of each instance of a variable length array type does not change during its lifetime. End of change. %% %% Change 19 %% [#3] For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present Replace the following words in C9XD9-pre3: they shall have the same value. With: and integer constant expressions, then both size specifiers shall have the same constant value. If the two array types are used in a context which requires them to be compatible, it is undefined behavior if the two size specifiers evaluate to unequal values. End of change. %% %% Change 20 %% Add the following as example 3 to 6.5.4.2 Array declarators: extern int n; extern int m; fcompat() { int a[n][6][m]; int (*p)[4][n+1]; int c[n][n][6][m]; int (*r)[n][n][n+1]; p = a; /* Error - not compatible because 4 != 6 */ r = c; /* compatible, but defined behavior only if n==6 and m==n+1 */ } End of change. %% %% Change 21 %% 6.5.4.3 Function declarators (including prototypes) [#5] A parameter type list specifies the types of, and may declare identifiers for, the parameters of the function. Add the following words to paragraph 5 above: A declared parameter that is a member of the parameter type list that is not part of a function definition, may use the [*] notation in its sequence of declarator specifiers to specify a variable length array type. End of change. %% %% Change 22 %% Add the following as examples 4 and 5 to 6.5.4.3 Function declarators: 4. The following prototype has a variably modified parameter. void addscalar(int n, int m, double a[n][n*m+300], double x); main() { double b[4][308]; addscalar(4, 2, b, 2.17); } void addscalar(int n, int m, double a[n][n*m+300], double x) { int i, j, k=n*m+300; for (i = 0; i < n; i++) for (j = 0; j < k; j++) a[i][j] += x; /* a is a pointer to a VLA with n*m+300 elements */ } 5. The following are all compatible function prototype declarators. double maximum(int n, int m, double a[n][m]); double maximum(int n, int m, double a[*][*]); double maximum(int n, int m, double a[ ][*]); double maximum(int n, int m, double a[ ][m]); End of change. %% %% Change 23 %% 6.5.6 Type definitions Add the following Constraint to 6.5.6 Type definitions: Constraints: If a typedef name specifies a variably modified type then it shall have block scope. End of change. %% %% Change 24 %% [#2] In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that specifies the type specified for the identifier in the way described in 6.5.4. Add the following words to paragraph 2 above: 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. End of change. %% %% Change 25 %% Add the following as examples 5 and 6 to 6.5.6 Type definitions: 5 The following is a block scope declaration of a typedef name "A" with a variable length array type. void tdef(int n) { typedef int A[n]; /* OK - declared with block scope */ A a; A *p; p = &a; } 6. The size expression that is part of the variable length array type named by typedef name "B" is evaluated each time function "copyt" is entered. However, the size of the variable length array type does not change if the value of "n" is subsequently changed. void copyt(int n) { typedef int B[n]; /* B is n ints with n evaluated now */ n += 1; { B a; /* a is n ints - n without += 1 */ int b[n]; /* a and b are different sizes */ for (i = 1; i < n; i++) a[i-1] = b[i]; } } End of change. %% %% Change 26 %% 6.5.7 Initialization Replace the following words in C9XD9-pre3: [#3] The type of the entity to be initialized shall be an object type or an array of unknown size. With: The type of the entity to be initialized shall be an object type that is not a variable length array type, or an array of unknown size. End of change. %% %% Change 27 %% 6.6.2 Compound statement, or block [#2] A compound statement (also called a block) allows a set of statements to be grouped into one syntactic unit, which may have its own set of declarations and initializations (as discussed in 6.1.2.4). The initializers of objects that have automatic storage duration Add the following words to paragraph 2 above: , and the variable length array declarators of ordinary identifiers with block scope ....... End of change. %% %% Change 28 %% 6.6.4.2 The "switch" statement [#1] The controlling expression of a "switch" statement shall have integral type Add the following words to paragraph 1 above: , 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. End of change. %% %% Change 29 %% There is no change 29. There used to be a change 29, but after reading editorial review committee comments, I decided the proposed example was unnecessary. However, I didn't want to renumber the remaining changes. End of change. %% %% Change 30 %% 6.6.6.1 The goto statement Add the following constraint as the second sentence to the Constraints of 6.6.6.1 The goto statement: A "goto" statement shall not cause a block to be entered by a jump from outside the block to a labeled statement in the block (or an enclosed block) if that block contains the declaration of a variably modified object or variably modified typedef name End of change. %% %% Change 31 %% Add the following example as the second example to 6.6.6.1 The goto statement: 2. A "goto" statment is not allowed to jump past any declarations of objects with variably modified types. A jump within the block, however, is permitted. goto lab3; /* Error - going INTO scope of variable length array */ { double a[n]; a[j] = 4.4; lab3: a[j] = 3.3; goto lab4; /* OK - going WITHIN scope of variable length array */ a[j] = 5.5; lab4: a[j] = 6.6; } goto lab4; /* Error - going INTO scope of variable length array */ End of change. %% %% Change 32 %% 6.7.1 Function definitions [#9] On entry to the function Add the following words to paragraph 9 above: all size expressions of its variably modified parameters are evaluated, and ..... End of change. %% %% Change 33 %% 7.6.2.1 The longjmp function Add the following example to the longjmp function: The "longjmp" function that returns control back to the point of the setjmp invocation might cause memory associated with a variable length array object to be squandered. #include jmp_buf buf; void g(int n); void h(int n); int n = 6; void f(void) { int x[n]; /* OK - "f" is not terminated */ setjmp(buf); g(n); } void g(int n) { int a[n]; /* "a" may remain allocated */ h(n); } void h(int n) { int b[n]; /* "b" may remain allocated */ longjmp(buf,2); /* might cause some memory to be lost */ } End of change. Language Syntax Summary ----------------------- X.1.2.2 Declarations (6.5.4) direct-declarator: identifier (declarator) direct-declarator [assignment-expression ] opt direct-declarator [* ] opt direct-declarator (parameter-type-list) direct-declarator (identifier-list ) opt (6.5.5) direct-abstract-declarator: (abstract-declarator) direct-abstract-declarator [assignment-expression ] opt direct-abstract-declarator [* ] opt direct-abstract-declarator (parameter-type-list ) opt ================================================================= === === === Other correspondence you might be interested in reading === === === ================================================================= From dmk@dmk.com Tue Apr 1 15:04 CST 1997 Date: Tue, 1 Apr 97 14:03:29 MST From: dmk@dmk.com (David Keaton) To: tam@cray.com Subject: Re: VLA Edits TMacD> Basically, it allows you to keep adding more precise information. TMacD> Don't know how useful this is in a program but still needs to be TMacD> specified. Thanks. Those examples helped. I agree that the usefulness of forming a composite type with an array of known constant size and a VLA is questionable, but should be specified. TMacD> An example for composite types is: TMacD> TMacD> void f(int [ ][*]); TMacD> void f(int [5][5]); TMacD> TMacD> In the above case the composite type is: TMacD> TMacD> void f(int [5][5]); TMacD> TMacD> and the parameter is no longer a VLA. It might be worthwhile to add this example just to make it obvious. However, since I don't think this technique will be used very often, I won't object if you don't want to add it. That's the only issue I had with the VLA changes. David ======================================================================== From tam@cray.com Thu Apr 3 13:38 CST 1997 From: Thomas MacDonald Subject: Re: VLA Edits To: dmk@dmk.com (David Keaton) Date: Thu, 3 Apr 1997 13:37:41 -0600 (CST) Thanks David. I've thought about this and decided that this is better left to rationale. So, I'll keep the example around. Tom MacDonald tam@cray.com ======================================================================== From Douglas.Walls@Eng.Sun.COM Wed Apr 16 13:43 CDT 1997 Date: Wed, 16 Apr 1997 09:06:46 -0700 From: Douglas.Walls@Eng.Sun.COM (Douglas Walls) To: dmk@dmk.com, seebs@solon.com, tam@cray.com Subject: Re: VLA Edits Tom, >Comments should be sent to me by April 15. Naturally, as I draft these comments, we have network problems and I am unable to send them on time. Apologies for sending them a day late. Douglas ---> %% ---> %% Change #7 ---> %% ---> ---> Add the following example to 6.3.6 Additive operators: ---> ---> Pointer arithmetic is still well defined with pointers to ^^^^^ This reads as if we are trying to convince someone of the merits of the proposal. Eliminating this word does not change the example's meaning. ---> variable length array types. ____________________ ---> %% ---> %% Change #10 ---> %% ---> ---> 6.5 Declarations ---> ---> 6.5.2 Type specifiers ---> ---> Add the following as a Constraint: Just to make it clear where to place this constraint: Add the following as a new paragraph to the end of the Constraints: ---> ---> Only ordinary identifiers (as defined in 6.1.2.3) with ---> block scope or function prototype scope and without linkage ---> can have a variably modified type. If an identifier is ---> declared to be an object with static storage duration, it ---> shall not have a variable length array type. ---> ---> End of change. ____________________ ---> %% ---> %% Change 20 ---> %% ---> ---> Add the following examples to 6.5.4.2 Array declarators: Just to make it clear where to add this example: Add the following as example 3 to 6.5.4.2 Array declarators: ____________________ ---> %% ---> %% Change 22 ---> %% ---> ---> Add the following examples to 6.5.4.3 Function declarators: Just to make it clear where to add this example: Add the following as examples 4 and 5 to 6.5.4.3 Function declarators: ____________________ ---> %% ---> %% Change 25 ---> %% ---> ---> Add the following examples to 6.5.6 Type definitions: There are four examples int 6.5.6 now, each with a number and leading. Where are these example suppose to go? ---> void tdef(int n) { ---> typedef int A[n]; /* OK - declared with block scope */ ---> A a; ---> A *p; ---> p = &a; ---> } ---> ---> void copyt(int n) { ---> typedef int A[n]; /* A is n ints with n evaluated now */ ---> n += 1; ---> { ---> A a; /* a is n ints - n without += 1 */ ---> int b[n]; /* a and b are different sizes */ ---> for (i = 1; i < n; i++) ---> a[i-1] = b[i]; ---> } ---> } ---> ---> End of change. ____________________ ---> %% ---> %% Change 27 ---> %% ---> ---> 6.6.2 Compound statement, or block ---> ---> [#2] A compound statement (also called a block) allows a set ---> of statements to be grouped into one syntactic unit, which ---> may have its own set of declarations and initializations (as ---> discussed in 6.1.2.4). The initializers of objects that ---> have automatic storage duration, ^ There is no comma in the original text. ---> ---> Add the following words to paragraph 2 above: ---> ---> and the variable length The comma belongs here --------------^ ---> array declarators of ordinary identifiers with block scope ---> ....... End of change. ____________________ ---> %% ---> %% Change 28 ---> %% ---> ---> 6.6.4.2 The "switch" statement ---> ---> [#1] The controlling expression of a "switch" statement shall ---> have integral type, ^ There is no comma in the original text. ---> ---> Add the following words to paragraph 1 above: ---> ---> and shall not cause a block to The comma belongs here-------^ ---> 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. End of change. ____________________ ---> %% ---> %% Change 29 ---> %% ---> ---> Add the following example to 6.6.4.2 The switch statement: This example needs some lead in text. Looking at the examples in 6.6.4.2 it is not clear where this example is suppose to go. ---> ---> switch (n) /* Error - bypasses declaration of a[n] */ ---> { ---> int a[n]; ---> case 10: ---> a[0] = 1; ---> break; ---> case 20: ---> a[0] = 2; ---> break; ---> default: ---> a[0] = 3; ---> break; ---> } ---> ---> End of change. ____________________ ---> %% ---> %% Change 30 ---> %% ---> ---> 6.6.6.1 The goto statement ---> ---> Add the following Constraint to 6.6.6.1 The goto statement: Just to make it clear where to place this constraint: Add the following Constraint as new constraint 2 to 6.6.6.1 The goto statement: ____________________ ---> %% ---> %% Change 31 ---> %% Where does this change go? How is it to be integrated with the existing example in 6.6.6.1? Or are we missing some lead in text and placement? ---> ---> goto lab3; /* Error - going INTO scope of variable length array */ ---> { ---> double a[n]; ---> a[j] = 4.4; ---> lab3: ---> a[j] = 3.3; ---> goto lab4; /* OK - going WITHIN scope of variable length array */ ---> a[j] = 5.5; ---> lab4: ---> a[j] = 6.6; ---> } ---> goto lab4; /* Error - going INTO scope of variable length array */ ---> ---> End of change. From homer@cray.com Fri May 9 17:32 CDT 1997 From: Bill Homer Subject: Re: And this To: tam@cray.com (Thomas MacDonald) Date: Fri, 9 May 1997 17:32:55 -0500 (CDT) Tom, I did see a typo and also have a few suggestions, but none are crucial. They are marked with '|' at the left. - Bill > %% > %% Change #1 > %% > > 6.1.2.4 Storage duration of objects > > [#3] An object whose identifier is declared with no linkage > and without the storage-class specifier static has automatic > storage duration. Storage is guaranteed to be reserved for > a new instance of such an object on each normal entry into > the block with which it is associated. ^ | omit punctuation here, because it changes > Replace the following words in C9XD9-pre3: ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | End the sentence in C9XD9-pre3 here, and replace its final clause: > > , or on a jump from > outside the block to a labeled statement in the block or in > an enclosed block. > > With the new complete sentences: > > . 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. > > End of change. > %% > %% Change #4 > %% > > 6.3 Expressions > > 6.3.3.4 The "sizeof" operator > > Semantics > > [#2] The "sizeof" operator yields the size (in bytes) of its > operand, which may be an expression or the parenthesized > name of a type. > > Replace the following words in C9XD9-pre3: > > The size is determined from the type of the > operand, which is not itself evaluated. The result is an > integer constant. > > With: > > The size is determined from the type of the operand. > The result is an integer. If the type of the operand > is a varaible length array type, the operand is evaluated; ^^^^^^^^ variable | > otherwise, the operand is not evaluated and the result is > an integer constant. > > End of change. > %% > %% Change #11 > %% > > Add the following example to 6.5.2 Type specifiers: > > All declarations of Variably Modified (VM) types must be declared at ^^^^^^^^^^^^^^^^^ | Why capitals here? They are not used in other places. > either block scope or function prototype scope. Array objects > declared with the "static" or "extern" storage class specifier cannot > have a Variable Length Array (VLA) type. However, a object declared ^^^^^^^^^^^^^^^^^^^^^ | Why capitals here? They are not used in other places. > with the "static" storage class specifier can have a VM type (that > is, a pointer to a VLA type). Finally, all identifiers declared > with a VM type must be ordinary identifiers, and can not, therefore, > be members of structures or unions. > > extern int n; > int A[n]; /* Error - file scope VLA */ > extern int (*p2)[n]; /* Error - file scope VM */ > int B[100]; /* OK - file scope but not VM */ > > void fvla(int m, int C[m][m]) { /* OK - VLA with prototype scope */ > typedef int VLA[m][m]; /* OK - block scope typedef VLA */ > /* array size m evaluated now */ > struct tag { > int (*y)[n]; /* Error - y is not an ordinary identifier */ > int z[n]; /* Error - z is not an ordinary identifier */ > }; > int D[m]; /* OK - auto VLA */ > static int E[m]; /* Error - static block scope VLA */ > extern int F[m]; /* Error - F has linkage and is a VLA */ > int (*s)[m]; /* OK - auto pointer to VLA */ > extern int (*r)[m]; /*Error - r has linkage and is a pointer to VLA*/ > static int (*q)[m] = &B; /* OK - q is a static block scope VM */ > > /* ... */ > > } > > End of change. > %% > %% Change 22 > %% > > Add the following as examples 4 and 5 to 6.5.4.3 Function declarators: > > 4. The following prototype has a variably modified parameter. > > void addscalar(int n, int m, double a[n][n*m+300], double x); > > main() { > double b[4][308]; > addscalar(4, 2, b, 2.17); > } > > void addscalar(int n, int m, double a[n][n*m+300], double x) { > int i, j, k=n*m+300; > > for (i = 0; i < n; i++) > for (j = 0; j < k; j++) > a[i][j] += x; /* a is a pointer to a VLA of size: n*m+300 */ ^^^^^^^^^^^^^^^^ | with n*m+300 elements > } > > > 5. The following are all compatible function prototype declarators. > > double maximum(int n, int m, double a[n][m]); > double maximum(int n, int m, double a[*][*]); > double maximum(int n, int m, double a[ ][*]); > double maximum(int n, int m, double a[ ][m]); > > End of change. > %% > %% Change 28 > %% > > 6.6.4.2 The "switch" statement > > [#1] The controlling expression of a "switch" statement shall > have integral type > > Add the following words to paragraph 1 above: > > , 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. | Maybe this is too big a change, but it seems like there is a | simpler alternative that is also statically checkable: If a declaration with a variably modified type is associated with a block that contains a case or default label of a switch statement, then that block shall contain the entire switch statement. > End of change. > %% > %% Change 30 > %% > > 6.6.6.1 The goto statement > > Add the following constraint as the second sentence to the Constraints of > 6.6.6.1 The goto statement: > > A "goto" statement shall not cause a block to be entered by > a jump from outside the block to a labeled statement in > the block (or an enclosed block) if that block contains > the declaration of a variably modified object or > variably modified typedef name | Analogous to the switch statement: If a declaration with a variably modified type is associated with a block that contains a label named in a goto statement, then that block shall also contain the goto statement. > End of change.