Clarify syntactic terms for array declarators

Jens Gustedt, INRIA and ICube, France

2024-11-19

target

integration into IS ISO/IEC 9899:202y

document history

document number date comment
n3393 202411 Original proposal

1 Motivation

The current wording of 6.7.7.3 is very confusing because it mixes up syntactic and semantic definitions in several places. In particular it introduces a term “size of an array” in the constraints section that is not properly defined; it is not clear what “specifies” means here. Later in the text even the case of a * token, which is just one other syntax derivation, is seemingly subsumed with that term. So is it a syntax element (the assignment expression or * token) or is it a semantic derivation (the value of that assignment expression, which does not exist for the * case)?

We propose to iron out these issues by changing the text to use already introduced terms and to make a clearer distinction of where the text talks about syntactic deduction and where it introduces semantic for that syntax.

2 Approach

We remove the confusing term “size of an array” by reverting its use to the one that appears in the syntax derivation, namely an assignment expression. Adding just this distinctive word in all places where the current text just talks about “expression”, should make things clearer.

In particular when it comes to the definition of compatible types, the current text gives a definition that only applies sensibly to the syntactic constructs, and that lack a consistent lift to the semantics. So we change this definition of compatibility to refer to the syntax construct “array declarator” (which is the subject of the clause) and only then lift this definition to array types in a second step.

Note that only the addition of the word integer in some places (upgrading the term “constant expression” to “integer constant expression”) is intended to be a normative change, all other modifications should not change the semantics. If that one normative change is not wanted by WG14, it can easily be omitted.

3 Suggested additions and changes to the wording.

New text is underlined green, removed text is stroke-out red.

3.1 to 6.2.7, Compatible type and composite type

in p3, second bullet

3.2 to 6.7.7.3, Array declarators

Constraints

1 In addition to optional type qualifiers and the keyword static, the [ and ] can delimit an assignment expression or a * token. If they delimit an assignment expression (which specifies the size of an array), the assignment expression shall have an integer type. If the assignment expression is an integer constant expression, it shall have a value greater than zero. The element type shall not be an incomplete or function type. The optional type qualifiers and the keyword static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.

2 …

Semantics

3 …

4 If the size is notneither an assignment expression nor the * token are present, the array type is an incomplete type. If the size is * instead of being an expression * token is present, the array type is a variable length array type of unspecified size, which can only be used as part of the nested sequence of declarators or abstract declarators for a parameter declaration, not including anything inside an array size expression any assignment expression in one of those declarators;161) such arrays are nonetheless complete types. If an assignment expression is present and evaluated, its value is the number of elements of the instance of the array type; this value is consequently denoted by size or length or an array. If the size expression it 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. (Variable length arrays with automatic storage duration are a conditional feature that implementations may support; see 6.10.10.4.)

5 If the size is an assignment expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by a * token; otherwise, each time it is evaluated it shall have a value greater than zero. The size of each instance of a variable length array type does not change during its lifetime. Where a size the assignment expression is part of the operand of a typeof or sizeof operator and changing the value of the size assignment expression would not affect the result of the operator, it is unspecified whether or not the size assignment expression is evaluated. Where a size the assignment expression is part of the operand of an alignof operator, that assignment expression is not evaluated.

6 For two array types declarators to be compatible, both shall have compatible element types, and if both size specifiers assignment expressions are present, and are integer constant expressions, then both size specifiers assignment expressions shall have the same constant value. Two array types are compatible if the array declarators that gave raise to them are compatible. If the two array types declarators are used or refered to in a context which requires them to be compatible, the behavior is undefined if the two size specifiers assignment expressions evaluate to unequal values.

11 EXAMPLE 5 The following is invalid, because the use of [*] is inside an array size assignment expression of and array declarator rather than directly part of the nested sequence of abstract declarators for a parameter declaration:

void f(int (*)[sizeof(int (*)[*])]);

3.3 to 6.7.9, Type definitions

3 In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that denotes the type specified for the identifier in the way described in 6.7.7. Any array size assignment expressions associated with variable length array declarators and typeof operators are evaluated each time the declaration of the typedef name is reached in the order of execution. A typedef declaration does not introduce a new type, only a synonym for the type so specified. That is, in the following declarations: …

3.4 to 6.7.11, Initialization

23 If an array of unknown size is initialized, its number of elements and indirectly its object size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list.

3.5 to 6.8.1

4 A full expression is an expression that is not part of another expression, nor part of a declarator or abstract declarator. There is also an implicit full expression in which the non-constant size an assignment expressions for a variably modified type of an array declarator that is not an integer constant expression are evaluated; within that full expression, the evaluation of different size assignment expressions of array declarators are unsequenced with respect to one another. There is a sequence point between the evaluation of a full expression and the evaluation of the next full expression to be evaluated.

3.6 to 7.21.2, the unreachable macro

In p4 make the following change

Here, the static array size adorned assignment expression of the array declarator and the annotation of the control flow with unreachable indicates that the pointed-to parameter array argv will hold at least three elements, regardless of the circumstances.

3.7 to J .1

  1. Whether a size expression an assignment expression of an array declarator is evaluated when it is part of the operand of a sizeof operator and changing the value of the size assignment expression would not affect the result of the operator (6.7.7.3)

3.8 to J .2

  1. A program requires the formation of a composite type from a variable length array type whose size is specified by an from an array declarator with an assignment expression that is not evaluated (6.2.7).
  1. The size expression in an array declaration assignment expression of an array declarator is not a an integer constant expression and evaluates at program execution time to a nonpositive value (6.7.7.3).
  1. In a context requiring two array types to be compatible, they do not have compatible element types, or their size specifiers the assignment expressions of their declarators evaluate to unequal values (6.7.7.3).

4 Interaction with other proposals

If n3392 is accepted concurrently, the additions of the word “assignment” above should instead read “reproducible”. Note that n3391 also proposes changes to 6.7.7.3, but that these are independent of each other.

Aknowledments

Thanks to Jakub Łukasiewicz for compiling a list of possible places that could be impacted by this change.