217 lines
9.0 KiB
Markdown
217 lines
9.0 KiB
Markdown
[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*]
|