From Jason Turner

[dcl.array]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5kvh9q9q/{from.md → to.md} +59 -39
tmp/tmp5kvh9q9q/{from.md → to.md} RENAMED
@@ -7,56 +7,65 @@ In a declaration `T` `D` where `D` has the form
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` , the program is ill-formed. `T` is called the array *element
13
- type*; this type shall not be a reference type, the (possibly
14
- cv-qualified) type `void`, a function type or an abstract class type. If
15
- the *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 “ array of `N` `T`”. An object of
21
- array type contains a contiguously allocated non-empty set of `N`
22
- subobjects of type `T`. Except as noted below, if the constant
23
- expression is omitted, the type of the identifier of `D` is “ array of
24
- unknown bound of `T`”, an incomplete object type. The type array of
25
- `N` `T`” is a different type from the type “ array of unknown bound of
26
- `T`”, see  [[basic.types]]. Any type of the form “ array of `N` `T`” is
27
- adjusted to “array of `N` `T`”, and similarly for “array of unknown
28
- bound of `T`”. The optional *attribute-specifier-seq* appertains to the
29
- array.
 
 
 
 
30
 
31
  ``` cpp
32
  typedef int A[5], AA[2][3];
33
  typedef const A CA; // type is ``array of 5 const int''
34
  typedef const AA CAA; // type is ``array of 2 array of 3 const int''
35
  ```
36
 
37
- An “array of `N` `T`” has cv-qualified type; see 
38
- [[basic.type.qualifier]].
 
 
39
 
40
  An array can be constructed from one of the fundamental types (except
41
  `void`), from a pointer, from a pointer to member, from a class, from an
42
  enumeration type, or from another array.
43
 
44
  When several “array of” specifications are adjacent, a multidimensional
45
- array is created; only the first of the constant expressions that
46
  specify the bounds of the arrays may be omitted. In addition to
47
  declarations in which an incomplete object type is allowed, an array
48
  bound may be omitted in some cases in the declaration of a function
49
  parameter ([[dcl.fct]]). An array bound may also be omitted when the
50
- declarator is followed by an *initializer* ([[dcl.init]]). In this case
51
- the bound is calculated from the number of initial elements (say, `N`)
52
- supplied ([[dcl.init.aggr]]), and the type of the identifier of `D` is
53
- “array of `N` `T`.” Furthermore, if there is a preceding declaration of
54
- the entity in the same scope in which the bound was specified, an
55
- omitted array bound is taken to be the same as in that earlier
56
- declaration, and similarly for the definition of a static data member of
57
- a class.
 
 
 
58
 
59
  ``` cpp
60
  float fa[17], *afp[17];
61
  ```
62
 
@@ -86,31 +95,38 @@ void f() {
86
  extern int x[];
87
  int i = sizeof(x); // error: incomplete object type
88
  }
89
  ```
90
 
91
- conversions affecting expressions of array type are described in 
92
- [[conv.array]]. Objects of array types cannot be modified, see 
93
- [[basic.lval]].
94
 
95
- Except where it has been declared for a class ([[over.sub]]), the
96
- subscript operator `[]` is interpreted in such a way that `E1[E2]` is
97
- identical to `*((E1)+(E2))`. Because of the conversion rules that apply
98
- to `+`, if `E1` is an array and `E2` an integer, then `E1[E2]` refers to
99
- the `E2`-th member of `E1`. Therefore, despite its asymmetric
100
- appearance, subscripting is a commutative operation.
 
 
 
 
 
 
 
101
 
102
  A consistent rule is followed for multidimensional arrays. If `E` is an
103
  *n*-dimensional array of rank i × j × … × k, then `E` appearing in an
104
  expression that is subject to the array-to-pointer conversion (
105
  [[conv.array]]) is converted to a pointer to an (n-1)-dimensional array
106
  with rank j × … × k. If the `*` operator, either explicitly or
107
  implicitly as a result of subscripting, is applied to this pointer, the
108
  result is the pointed-to (n-1)-dimensional array, which itself is
109
  immediately converted into a pointer.
110
 
111
- consider
 
 
112
 
113
  ``` cpp
114
  int x[3][5];
115
  ```
116
 
@@ -123,10 +139,14 @@ multiplying `i` by the length of the object to which the pointer points,
123
  namely five integer objects. The results are added and indirection
124
  applied to yield an array (of five integers), which in turn is converted
125
  to a pointer to the first of the integers. If there is another subscript
126
  the same argument applies again; this time the result is an integer.
127
 
128
- It follows from all this that arrays in C++are stored row-wise (last
129
- subscript varies fastest) and that the first subscript in the
130
- declaration helps determine the amount of storage consumed by an array
131
- but plays no other part in subscript calculations.
 
 
 
 
132
 
 
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
 
 
95
  extern int x[];
96
  int i = sizeof(x); // error: incomplete object type
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
 
 
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