From Jason Turner

[dcl.array]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp2g6qidvz/{from.md → to.md} +100 -100
tmp/tmp2g6qidvz/{from.md → to.md} RENAMED
@@ -1,88 +1,93 @@
1
- ### Arrays <a id="dcl.array">[[dcl.array]]</a>
2
 
3
  In a declaration `T` `D` where `D` has the form
4
 
5
  ``` bnf
6
- 'D1 [' constant-expressionₒₚₜ ']' attribute-specifier-seqₒₚₜ
7
  ```
8
 
9
- and the type of the identifier in the declaration `T` `D1` is
10
- “*derived-declarator-type-list* `T`”, then the type of the identifier of
11
- `D` is an array type; if the type of the identifier of `D` contains the
12
- `auto` *type-specifier*, the program is ill-formed. `T` is called the
13
- array *element type*; this type shall not be a reference type,
14
- cv `void`, a function type or an abstract class type. If the
15
- *constant-expression* ([[expr.const]]) is present, it shall be a
16
- converted constant expression of type `std::size_t` and its value shall
17
- be greater than zero. The constant expression specifies the *bound* of
18
- (number of elements in) the array. If the value of the constant
19
- expression is `N`, the array has `N` elements numbered `0` to `N-1`, and
20
- the type of the identifier of `D` is “*derived-declarator-type-list*
21
- array of `N` `T`”. An object of array type contains a contiguously
22
- allocated non-empty set of `N` subobjects of type `T`. Except as noted
23
- below, if the constant expression is omitted, the type of the identifier
24
- of `D` is “*derived-declarator-type-list* array of unknown bound of
25
- `T`”, an incomplete object type. The type
26
- “*derived-declarator-type-list* array of `N` `T`” is a different type
27
- from the type “*derived-declarator-type-list* array of unknown bound of
28
- `T`”, see  [[basic.types]]. Any type of the form “*cv-qualifier-seq*
29
- array of `N` `T`” is adjusted to “array of `N` *cv-qualifier-seq* `T`”,
30
- and similarly for “array of unknown bound of `T`”. The optional
31
- *attribute-specifier-seq* appertains to the array.
 
 
 
 
 
 
 
 
32
 
33
  [*Example 1*:
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  ``` cpp
36
  typedef int A[5], AA[2][3];
37
  typedef const A CA; // type is ``array of 5 const int''
38
  typedef const AA CAA; // type is ``array of 2 array of 3 const int''
39
  ```
40
 
41
  — *end example*]
42
 
43
- [*Note 1*: An “array of `N` *cv-qualifier-seq* `T`” has cv-qualified
44
  type; see  [[basic.type.qualifier]]. — *end note*]
45
 
46
- An array can be constructed from one of the fundamental types (except
47
- `void`), from a pointer, from a pointer to member, from a class, from an
48
- enumeration type, or from another array.
49
 
50
- When several “array of” specifications are adjacent, a multidimensional
51
- array type is created; only the first of the constant expressions that
52
- specify the bounds of the arrays may be omitted. In addition to
53
- declarations in which an incomplete object type is allowed, an array
54
- bound may be omitted in some cases in the declaration of a function
55
- parameter ([[dcl.fct]]). An array bound may also be omitted when the
56
- declarator is followed by an *initializer* ([[dcl.init]]) or when a
57
- declarator for a static data member is followed by a
58
- *brace-or-equal-initializer* ([[class.mem]]). In both cases the bound
59
- is calculated from the number of initial elements (say, `N`) supplied (
60
- [[dcl.init.aggr]]), and the type of the identifier of `D` is “array of
61
- `N` `T`”. Furthermore, if there is a preceding declaration of the entity
62
- in the same scope in which the bound was specified, an omitted array
63
- bound is taken to be the same as in that earlier declaration, and
64
- similarly for the definition of a static data member of a class.
65
 
66
- [*Example 2*:
 
 
 
67
 
68
- ``` cpp
69
- float fa[17], *afp[17];
70
- ```
71
-
72
- declares an array of `float` numbers and an array of pointers to `float`
73
- numbers. For another example,
74
-
75
- ``` cpp
76
- static int x3d[3][5][7];
77
- ```
78
-
79
- declares a static three-dimensional array of integers, with rank
80
- 3 × 5 × 7. In complete detail, `x3d` is an array of three items; each
81
- item is an array of five arrays; each of the latter arrays is an array
82
- of seven integers. Any of the expressions `x3d`, `x3d[i]`, `x3d[i][j]`,
83
- `x3d[i][j][k]` can reasonably appear in an expression. Finally,
84
 
85
  ``` cpp
86
  extern int x[10];
87
  struct S {
88
  static int y[10];
@@ -97,56 +102,51 @@ void f() {
97
  }
98
  ```
99
 
100
  — *end example*]
101
 
102
- [*Note 2*: Conversions affecting expressions of array type are
103
- described in  [[conv.array]]. Objects of array types cannot be modified,
104
- see  [[basic.lval]]. — *end note*]
105
 
106
- [*Note 3*: Except where it has been declared for a class (
107
- [[over.sub]]), the subscript operator `[]` is interpreted in such a way
108
- that `E1[E2]` is identical to `*((E1)+(E2))` ([[expr.sub]]). Because of
109
- the conversion rules that apply to `+`, if `E1` is an array and `E2` an
110
- integer, then `E1[E2]` refers to the `E2`-th member of `E1`. Therefore,
111
- despite its asymmetric appearance, subscripting is a commutative
112
- operation. — *end note*]
113
 
114
- [*Note 4*:
115
-
116
- A consistent rule is followed for multidimensional arrays. If `E` is an
117
- *n*-dimensional array of rank i × j × … × k, then `E` appearing in an
118
- expression that is subject to the array-to-pointer conversion (
119
- [[conv.array]]) is converted to a pointer to an (n-1)-dimensional array
120
- with rank j × … × k. If the `*` operator, either explicitly or
121
- implicitly as a result of subscripting, is applied to this pointer, the
122
- result is the pointed-to (n-1)-dimensional array, which itself is
123
- immediately converted into a pointer.
124
-
125
- [*Example 3*:
126
-
127
- Consider
128
 
129
  ``` cpp
130
- int x[3][5];
131
  ```
132
 
133
- Here `x` is a 3 × 5 array of integers. When `x` appears in an
134
- expression, it is converted to a pointer to (the first of three)
135
- five-membered arrays of integers. In the expression `x[i]` which is
136
- equivalent to `*(x+i)`, `x` is first converted to a pointer as
137
- described; then `x+i` is converted to the type of `x`, which involves
138
- multiplying `i` by the length of the object to which the pointer points,
139
- namely five integer objects. The results are added and indirection
140
- applied to yield an array (of five integers), which in turn is converted
141
- to a pointer to the first of the integers. If there is another subscript
142
- the same argument applies again; this time the result is an integer.
 
 
 
 
 
 
 
 
143
 
144
  — *end example*]
145
 
 
 
 
 
146
  — *end note*]
147
 
148
- [*Note 5*: It follows from all this that arrays in C++are stored
149
- row-wise (last subscript varies fastest) and that the first subscript in
150
- the declaration helps determine the amount of storage consumed by an
151
- array but plays no other part in subscript calculations. *end note*]
 
 
152
 
 
1
+ #### Arrays <a id="dcl.array">[[dcl.array]]</a>
2
 
3
  In a declaration `T` `D` where `D` has the form
4
 
5
  ``` bnf
6
+ 'D1' '[' constant-expressionₒₚₜ ']' attribute-specifier-seqₒₚₜ
7
  ```
8
 
9
+ and the type of the contained *declarator-id* in the declaration `T`
10
+ `D1` is “*derived-declarator-type-list* `T`”, the type of the
11
+ *declarator-id* in `D` is “*derived-declarator-type-list* array of `N`
12
+ `T`”. The *constant-expression* shall be a converted constant expression
13
+ of type `std::size_t` [[expr.const]]. Its value `N` specifies the *array
14
+ bound*, i.e., the number of elements in the array; `N` shall be greater
15
+ than zero.
16
+
17
+ In a declaration `T` `D` where `D` has the form
18
+
19
+ ``` bnf
20
+ 'D1 [ ]' attribute-specifier-seqₒₚₜ
21
+ ```
22
+
23
+ and the type of the contained *declarator-id* in the declaration `T`
24
+ `D1` is “*derived-declarator-type-list* `T`”, the type of the
25
+ *declarator-id* in `D` is “*derived-declarator-type-list* array of
26
+ unknown bound of `T`”, except as specified below.
27
+
28
+ A type of the form “array of `N` `U`” or “array of unknown bound of `U`”
29
+ is an *array type*. The optional *attribute-specifier-seq* appertains to
30
+ the array type.
31
+
32
+ `U` is called the array *element type*; this type shall not be a
33
+ placeholder type [[dcl.spec.auto]], a reference type, a function type,
34
+ an array of unknown bound, or cv `void`.
35
+
36
+ [*Note 1*: An array can be constructed from one of the fundamental
37
+ types (except `void`), from a pointer, from a pointer to member, from a
38
+ class, from an enumeration type, or from an array of known
39
+ bound. — *end note*]
40
 
41
  [*Example 1*:
42
 
43
+ ``` cpp
44
+ float fa[17], *afp[17];
45
+ ```
46
+
47
+ declares an array of `float` numbers and an array of pointers to `float`
48
+ numbers.
49
+
50
+ — *end example*]
51
+
52
+ Any type of the form “*cv-qualifier-seq* array of `N` `U`” is adjusted
53
+ to “array of `N` *cv-qualifier-seq* `U`”, and similarly for “array of
54
+ unknown bound of `U`”.
55
+
56
+ [*Example 2*:
57
+
58
  ``` cpp
59
  typedef int A[5], AA[2][3];
60
  typedef const A CA; // type is ``array of 5 const int''
61
  typedef const AA CAA; // type is ``array of 2 array of 3 const int''
62
  ```
63
 
64
  — *end example*]
65
 
66
+ [*Note 2*: An “array of `N` *cv-qualifier-seq* `U`” has cv-qualified
67
  type; see  [[basic.type.qualifier]]. — *end note*]
68
 
69
+ An object of type “array of `N` `U`” contains a contiguously allocated
70
+ non-empty set of `N` subobjects of type `U`, known as the *elements* of
71
+ the array, and numbered `0` to `N-1`.
72
 
73
+ In addition to declarations in which an incomplete object type is
74
+ allowed, an array bound may be omitted in some cases in the declaration
75
+ of a function parameter [[dcl.fct]]. An array bound may also be omitted
76
+ when an object (but not a non-static data member) of array type is
77
+ initialized and the declarator is followed by an initializer (
78
+ [[dcl.init]], [[class.mem]], [[expr.type.conv]], [[expr.new]]). In these
79
+ cases, the array bound is calculated from the number of initial elements
80
+ (say, `N`) supplied [[dcl.init.aggr]], and the type of the array is
81
+ “array of `N` `U`”.
 
 
 
 
 
 
82
 
83
+ Furthermore, if there is a preceding declaration of the entity in the
84
+ same scope in which the bound was specified, an omitted array bound is
85
+ taken to be the same as in that earlier declaration, and similarly for
86
+ the definition of a static data member of a class.
87
 
88
+ [*Example 3*:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  ``` cpp
91
  extern int x[10];
92
  struct S {
93
  static int y[10];
 
102
  }
103
  ```
104
 
105
  — *end example*]
106
 
107
+ [*Note 3*:
 
 
108
 
109
+ When several “array of” specifications are adjacent, a multidimensional
110
+ array type is created; only the first of the constant expressions that
111
+ specify the bounds of the arrays may be omitted.
 
 
 
 
112
 
113
+ [*Example 4*:
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  ``` cpp
116
+ int x3d[3][5][7];
117
  ```
118
 
119
+ declares an array of three elements, each of which is an array of five
120
+ elements, each of which is an array of seven integers. The overall array
121
+ can be viewed as a three-dimensional array of integers, with rank
122
+ 3 × 5 × 7. Any of the expressions `x3d`, `x3d[i]`, `x3d[i][j]`,
123
+ `x3d[i][j][k]` can reasonably appear in an expression. The expression
124
+ `x3d[i]` is equivalent to `*(x3d + i)`; in that expression, `x3d` is
125
+ subject to the array-to-pointer conversion [[conv.array]] and is first
126
+ converted to a pointer to a 2-dimensional array with rank 5 × 7 that
127
+ points to the first element of `x3d`. Then `i` is added, which on
128
+ typical implementations involves multiplying `i` by the length of the
129
+ object to which the pointer points, which is `sizeof(int)`× 5 × 7. The
130
+ result of the addition and indirection is an lvalue denoting the `i`ᵗʰ
131
+ array element of `x3d` (an array of five arrays of seven integers). If
132
+ there is another subscript, the same argument applies again, so
133
+ `x3d[i][j]` is an lvalue denoting the `j`ᵗʰ array element of the `i`ᵗʰ
134
+ array element of `x3d` (an array of seven integers), and `x3d[i][j][k]`
135
+ is an lvalue denoting the `k`ᵗʰ array element of the `j`ᵗʰ array element
136
+ of the `i`ᵗʰ array element of `x3d` (an integer).
137
 
138
  — *end example*]
139
 
140
+ The first subscript in the declaration helps determine the amount of
141
+ storage consumed by an array but plays no other part in subscript
142
+ calculations.
143
+
144
  — *end note*]
145
 
146
+ [*Note 4*: Conversions affecting expressions of array type are
147
+ described in  [[conv.array]]. *end note*]
148
+
149
+ [*Note 5*: The subscript operator can be overloaded for a class
150
+ [[over.sub]]. For the operator’s built-in meaning, see
151
+ [[expr.sub]]. — *end note*]
152