Files
cppdraft_translate/cppdraft/dcl/array.md
2025-10-25 03:02:53 +03:00

217 lines
9.0 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.7Constant expressions[expr.const]")opt ] [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[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.1General[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.7Constant expressions[expr.const]") shall be a converted constant expression of type std::size_t ([[expr.const]](expr.const "7.7Constant expressions"))[.](#1.sentence-2)
Its value N specifies the [*array bound*](#def:array,bound "9.3.4.5Arrays[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.1Attribute syntax and semantics[dcl.attr.grammar]")opt
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[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.1General[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.5Arrays[dcl.array]")[.](#3.sentence-1)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute 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.5Arrays[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.1General[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.1General[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.1General[dcl.decl.general]") U”
has cv-qualified type; see [[basic.type.qualifier]](basic.type.qualifier "6.9.5CV-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.5Arrays[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.6Functions"))[.](#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.5Initializers"), [[class.mem]](class.mem "11.4Class members"), [[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.new]](expr.new "7.6.2.8New"))[.](#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.2Aggregates")),
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.1General")),
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.3Array-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.3Array-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.5Subscripting"))[.](#11.sentence-1)
For the operator's built-in meaning, see [[expr.sub]](expr.sub "7.6.1.2Subscripting")[.](#11.sentence-2)
— *end note*]