1553
In addition to optional type qualifiers and the keyword
1554 If they delimit an expression (which specifies the size of an array), the expression shall have an integer type.
1555 If the expression is a constant expression, it shall have a value greater than zero.
1556 The element type shall not be an incomplete or function type.
1557
The optional type qualifiers and the keyword
1558 Only an ordinary identifier (as defined in 6.2.3) with both block scope or function prototype scope and no linkage shall have a variably modified type.
1559 If an identifier is declared to be an object with static storage duration, it shall not have a variable length array type.
1560
If, in the declaration
D [ type-qualifier-listopt assignment-expressionopt ] D [ static type-qualifier-listopt assignment-expression ] D [ type-qualifier-list static assignment-expression ] D [ type-qualifier-listopt * ]
and the type specified for ident in the declaration
1561
(See 6.7.5.3 for the meaning of the optional type qualifiers and the
keyword
1562 If the size is not present, the array type is an incomplete type.
1563
If the size is
1564 such arrays are nonetheless complete types.
1565 If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type;
1566 121) When several array of specifications are adjacent, a multidimensional array is declared.
1567
122) Thus,
1568 otherwise, the array type is a variable length array type.
1569 If the size is an expression that is not an integer constant expression:
1570
if it occurs in a declaration at function prototype scope, it is
treated as if it were replaced by
1571 otherwise, each time it is evaluated it shall have a value greater than zero.
1572 The size of each instance of a variable length array type does not change during its lifetime.
1573
Where a size expression is part of the operand of a
1574 For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value.
1575 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.
1576 EXAMPLE 1
float fa[11], *afp[17];
declares an array of
1577 EXAMPLE 2 Note the distinction between the declarations
extern int *x;
extern int y[];
The first declares
1578 EXAMPLE 3 The following declarations demonstrate the compatibility rules for variably modified types.
extern int n;
extern int m;
void fcompat(void)
{
int a[n][6][m];
int (*p)[4][n+1];
int c[n][n][6][m];
int (*r)[n][n][n+1];
p = a; // invalid: not compatible because 4 != 6
r = c; // compatible, but defined behavior only if
// n == 6 and m == n+1
}
1579
EXAMPLE 4
All declarations of variably modified (VM) types have to be at either
block scope or function prototype scope. Array objects declared with
the
extern int n;
int A[n]; // invalid: file scope VLA
extern int (*p2)[n]; // invalid: file scope VM
int B[100]; // valid: file scope but not VM
void fvla(int m, int C[m][m]); // valid: VLA with prototype scope
void fvla(int m, int C[m][m]) // valid: adjusted to auto pointer to VLA
{
typedef int VLA[m][m]; // valid: block scope typedef VLA
struct tag {
int (*y)[n]; // invalid: y not ordinary identifier
int z[n]; // invalid: z not ordinary identifier
};
int D[m]; // valid: auto VLA
static int E[m]; // invalid: static block scope VLA
extern int F[m]; // invalid: F has linkage and is VLA
int (*s)[m]; // valid: auto pointer to VLA
extern int (*r)[m]; // invalid: r has linkage and points to VLA
static int (*q)[m] = &B; // valid: q is a static block pointer to VLA
}
1580 Forward references: function declarators (6.7.5.3), function definitions (6.9.1), initialization (6.7.8).
Next
Created at: 2005-06-29 02:19:02
The text from WG14/N1124 is copyright © ISO