[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*]
