6.7.5.2 Array declarators

Previous Table of Contents

1553 In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *.

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 static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.

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 “T D1”, D1 has one of the forms:

        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 “T D” is “derived-declarator-type-list T”, then the type specified for ident is “derived-declarator-type-list array of T”.121)

1561 (See 6.7.5.3 for the meaning of the optional type qualifiers and the keyword static.)

1562 If the size is not present, the array type is an incomplete type.

1563 If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope;122)

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, * can be used only in function declarations that are not definitions (see 6.7.5.3).

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 sizeof operator and changing the value of the size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated.

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 float numbers and an array of pointers to float numbers.

1577 EXAMPLE 2 Note the distinction between the declarations


        extern int *x;
        extern int y[];

The first declares x to be a pointer to int; the second declares y to be an array of int of unspecified size (an incomplete type), the storage for which is defined elsewhere.

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 static or extern storage-class specifier cannot have a variable length array (VLA) type. However, an 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 have to be ordinary identifiers and cannot, therefore, be members of structures or unions.


        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