[dcl.array] # 9 Declarations [[dcl]](./#dcl) ## 9.3 Declarators [[dcl.decl]](dcl.decl#dcl.array) ### 9.3.4 Meaning of declarators [[dcl.meaning]](dcl.meaning#dcl.array) #### 9.3.4.5 Arrays [dcl.array] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3465) In a declaration T D where D has the form D1 [ [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]")opt ] [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declaration T D1 is “*derived-declarator-type-list* T”, the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in D is “*derived-declarator-type-list* array of N T”[.](#1.sentence-1) The [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") shall be a converted constant expression of type std​::​size_t ([[expr.const]](expr.const "7.7 Constant expressions"))[.](#1.sentence-2) Its value N specifies the [*array bound*](#def:array,bound "9.3.4.5 Arrays [dcl.array]"), i.e., the number of elements in the array;N shall be greater than zero[.](#1.sentence-3) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3482) In a declaration T D where D has the form D1 [ ] [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declaration T D1 is “*derived-declarator-type-list* T”, the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in D is “*derived-declarator-type-list* array of unknown bound of T”, except as specified below[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3493) A type of the form “array of N U” or “array of unknown bound of U” is an [*array type*](#def:array_type "9.3.4.5 Arrays [dcl.array]")[.](#3.sentence-1) The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the array type[.](#3.sentence-2) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3501) U is called the array [*element type*](#def:element_type "9.3.4.5 Arrays [dcl.array]"); this type shall not be a reference type, a function type, an array of unknown bound, orcv void[.](#4.sentence-1) [*Note [1](#note-1)*: An array can be constructed from one of the fundamental types (except void), from a pointer, from a pointer to member, from a class, from an enumeration type, or from an array of known bound[.](#4.sentence-2) — *end note*] [*Example [1](#example-1)*: float fa[17], *afp[17]; declares an array of float numbers and an array of pointers to float numbers[.](#4.sentence-3) — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3525) Any type of the form “[*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") array of N U” is adjusted to “array of N [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") U”, and similarly for “array of unknown bound of U”[.](#5.sentence-1) [*Example [2](#example-2)*: typedef int A[5], AA[2][3];typedef const A CA; // type is “array of 5 const int''typedef const AA CAA; // type is “array of 2 array of 3 const int'' — *end example*] [*Note [2](#note-2)*: An “array of N [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") U” has cv-qualified type; see [[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")[.](#5.sentence-2) — *end note*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3543) An object of type “array of N U” consists of a contiguously allocated non-empty set of N subobjects of type U, known as the [*elements*](#def:array,element "9.3.4.5 Arrays [dcl.array]") of the array, and numbered 0 to N-1[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3550) In addition to declarations in which an incomplete object type is allowed, an array bound may be omitted in some cases in the declaration of a function parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#7.sentence-1) An array bound may also be omitted when an object (but not a non-static data member) of array type is initialized and the declarator is followed by an initializer ([[dcl.init]](dcl.init "9.5 Initializers"), [[class.mem]](class.mem "11.4 Class members"), [[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.new]](expr.new "7.6.2.8 New"))[.](#7.sentence-2) In these cases, the array bound is calculated from the number of initial elements (say, N) supplied ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")), and the type of the array is “array of N U”[.](#7.sentence-3) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3564) Furthermore, if there is a reachable declaration of the entity that specifies a bound and has the same host scope ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")), an omitted array bound is taken to be the same as in that earlier declaration, and similarly for the definition of a static data member of a class[.](#8.sentence-1) [*Example [3](#example-3)*: extern int x[10];struct S {static int y[10];}; int x[]; // OK, bound is 10int S::y[]; // OK, bound is 10void f() {extern int x[]; int i = sizeof(x); // error: incomplete object type}namespace A { extern int z[3]; }int A::z[] = {}; // OK, defines an array of 3 elements — *end example*] [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3591) [*Note [3](#note-3)*: When several “array of” specifications are adjacent, a multidimensional array type is created; only the first of the constant expressions that specify the bounds of the arrays can be omitted[.](#9.sentence-1) [*Example [4](#example-4)*: int x3d[3][5][7]; declares an array of three elements, each of which is an array of five elements, each of which is an array of seven integers[.](#9.sentence-2) The overall array can be viewed as a three-dimensional array of integers, with rank 3 ×5 ×7[.](#9.sentence-3) Any of the expressionsx3d,x3d[i],x3d[i][j],x3d[i][j][k] can reasonably appear in an expression[.](#9.sentence-4) The expressionx3d[i] is equivalent to*(x3d + i); in that expression,x3d is subject to the array-to-pointer conversion ([[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")) and is first converted to a pointer to a 2-dimensional array with rank5 ×7 that points to the first element of x3d[.](#9.sentence-5) Then i is added, which on typical implementations involves multiplyingi by the length of the object to which the pointer points, which is sizeof(int)×5 ×7[.](#9.sentence-6) The result of the addition and indirection is an lvalue denoting the ith array element ofx3d (an array of five arrays of seven integers)[.](#9.sentence-7) If there is another subscript, the same argument applies again, sox3d[i][j] is an lvalue denoting the jth array element of the ith array element ofx3d (an array of seven integers), andx3d[i][j][k] is an lvalue denoting the kth array element of the jth array element of the ith array element ofx3d (an integer)[.](#9.sentence-8) — *end example*] The first subscript in the declaration helps determine the amount of storage consumed by an array but plays no other part in subscript calculations[.](#9.sentence-9) — *end note*] [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3657) [*Note [4](#note-4)*: Conversions affecting expressions of array type are described in [[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")[.](#10.sentence-1) — *end note*] [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3662) [*Note [5](#note-5)*: The subscript operator can be overloaded for a class ([[over.sub]](over.sub "12.4.5 Subscripting"))[.](#11.sentence-1) For the operator's built-in meaning, see [[expr.sub]](expr.sub "7.6.1.2 Subscripting")[.](#11.sentence-2) — *end note*]