Skip to content

Commit 25f376c

Browse files
authored
Fix Bugzilla 24890 - spec/arrays.dd should mention comparison and war… (#3930)
* Fix Bugzilla 24890 - spec/arrays.dd should mention comparison and warn about dangling .ptr Add comparison section. Introduce .length earlier in the docs. Define `a == b` and `a is b` for arrays. Add link to array RelExpression. Tweak assignment example so comments refer to actual elements. Make *Array Length* a sub-heading of slicing. Add relative links for properties. Document that static array .length is known at compile-time. Add .ptr section. Document that .ptr can be dangling so it's not `@safe`. Mention `TypeInfo.initializer`. * Remove note about TypeInfo.initializer (not really needed) * Fix dynamic array .init
1 parent 615d4be commit 25f376c

File tree

2 files changed

+73
-20
lines changed

2 files changed

+73
-20
lines changed

spec/arrays.dd

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,32 @@ f([1, 2]); // pass 2 elements
124124
f([]); // pass an empty array
125125
---
126126

127+
$(H2 $(LNAME2 comparison, Array Comparison))
128+
129+
$(P For static and dynamic arrays:)
130+
131+
* The `.length` property will give the number of elements in the array.
132+
* The $(RELATIVE_LINK2 ptr-property, `.ptr` property) will give a pointer to
133+
the first element in the array.
134+
* `a == b` compares both the array lengths and array elements.
135+
* `a is b` compares each `.ptr` and each `.length`. Note that this is
136+
deprecated for static arrays because those are value types, so checking
137+
identity should not compare the `.ptr` fields.)
138+
139+
$(SPEC_RUNNABLE_EXAMPLE_RUN
140+
---------
141+
int[3] s = [1, 2, 3];
142+
int[] a = [1, 2, 3];
143+
144+
assert(s.length == 3);
145+
assert(a.length == 3);
146+
assert(s == a);
147+
assert(s.ptr != a.ptr); // here `a` is not a slice of `s`
148+
assert(s !is a);
149+
---
150+
)
151+
$(P See also: $(DDSUBLINK spec/expression, array_comparisons, *RelExpression*.)
152+
127153
$(LEGACY_LNAME2 usage)
128154
$(H2 $(LNAME2 assignment, Array Assignment))
129155

@@ -133,17 +159,16 @@ $(H2 $(LNAME2 assignment, Array Assignment))
133159
the handle for these types.
134160
)
135161

136-
$(P The `.ptr` property for static and dynamic arrays will give the address
137-
of the first element in the array:)
138-
139162
$(SPEC_RUNNABLE_EXAMPLE_RUN
140163
---------
141164
int* p;
142165
int[3] s;
143166
int[] a;
144167

145168
p = s.ptr; // p points to the first element of the array s.
146-
p = a.ptr; // p points to the first element of the array a.
169+
assert(p !is null);
170+
p = a.ptr;
171+
assert(p is null);
147172

148173
// error, since the length of the array pointed to by p is unknown
149174
//s = p;
@@ -152,10 +177,10 @@ p = a.ptr; // p points to the first element of the array a.
152177
a = s; // a points to the elements of s
153178
assert(a.ptr == s.ptr);
154179

155-
int[] b;
180+
int[] b = [1, 2, 3];
156181
a = b; // a points to the same array as b does
157182
assert(a.ptr == b.ptr);
158-
assert(a == []);
183+
assert(a is b);
159184
---------
160185
)
161186
$(NOTE The two error lines above can be made to copy elements
@@ -176,7 +201,9 @@ s = [1, 2, 3]; // OK
176201

177202
a = [4, 5, 6];
178203
s = a; // OK
204+
assert(s == a);
179205
assert(s.ptr != a.ptr);
206+
180207
a = [1, 2];
181208
//s = a; // RangeError, length mismatch
182209

@@ -293,10 +320,7 @@ writeln(b[7]); // 10
293320
$(P See also $(GLINK2 expression, SliceOperation).)
294321

295322

296-
$(H2 $(LNAME2 array-length, Array Length))
297-
298-
$(P The $(RELATIVE_LINK2 array-properties, `.length` property)
299-
for static and dynamic arrays gives the number of elements in the array.)
323+
$(H3 $(LNAME2 array-length, Array Length))
300324

301325
$(P When indexing or slicing a static or dynamic array,
302326
the symbol $(D $) represents the length of the array.
@@ -626,9 +650,11 @@ $(H2 $(LNAME2 array-properties, Array Properties))
626650
Returns an array literal with each element of the literal being the $(D .init) property of the array element type.)
627651
$(TROW $(D .sizeof), Returns the array length multiplied by
628652
the number of bytes per array element.)
629-
$(TROW $(D .length), Returns the number of elements in the array.
630-
This is a fixed quantity for static arrays. It is of type $(D size_t).)
631-
$(TROW $(D .ptr), Returns a pointer to the first element of the array.)
653+
$(TROW $(D .length), $(ARGS Returns the number of elements in the array.
654+
This is a fixed quantity for static arrays, known at compile-time.
655+
It is of type $(D size_t)).)
656+
$(TROW $(RELATIVE_LINK2 ptr-property, `.ptr`), Returns a pointer to the first
657+
element of the array.)
632658
$(TROW $(D .dup), Create a dynamic array of the same size and copy the contents of the array into it. The copy will have any immutability or const stripped. If this conversion is invalid the call will not compile.)
633659
$(TROW $(D .idup), Create a dynamic array of the same size and copy the contents of the array into it. The copy is typed as being immutable. If this conversion is invalid the call will not compile.)
634660
$(TROW $(D .tupleof), $(ARGS Returns an $(DDSUBLINK spec/template, lvalue-sequences, lvalue sequence) of each element in the array:
@@ -652,15 +678,14 @@ Returns an array literal with each element of the literal being the $(D .init) p
652678

653679
$(TABLE_2COLS Dynamic Array Properties,
654680
$(THEAD Property, Description)
655-
$(TROW $(D .init), Returns $(D null).)
681+
$(TROW $(D .init), Returns $(D []).)
656682
$(TROW $(D .sizeof), $(ARGS Returns the size of the dynamic array reference,
657683
which is 8 in 32-bit builds and 16 on 64-bit builds.))
658-
$(TROW $(D .length), Get/set number of elements in the
684+
$(TROW $(RELATIVE_LINK2 resize, `.length`), Get/set number of elements in the
659685
array. It is of type $(D size_t).)
660-
$(TROW $(D .capacity), Returns the length an array can grow to without reallocating.
661-
See $(RELATIVE_LINK2 capacity-reserve, here) for details.)
662-
$(TROW $(D .ptr), Returns a pointer to the first element of the array.
663-
See $(RELATIVE_LINK2 assignment, assignment).)
686+
$(TROW $(RELATIVE_LINK2 capacity-reserve, `.capacity`), Returns the length an array can grow to without reallocating.)
687+
$(TROW $(RELATIVE_LINK2 ptr-property, `.ptr`), Returns a pointer to the first
688+
element of the array.)
664689
$(TROW $(D .dup), Create a dynamic array of the same size and copy the contents of the array into it. The copy will have any immutability or const stripped. If this conversion is invalid the call will not compile.)
665690
$(TROW $(D .idup), Create a dynamic array of the same size and copy the contents of the array into it. The copy is typed as being immutable. If this conversion is invalid the call will not compile.)
666691
)
@@ -693,6 +718,33 @@ assert(b !is a); // b is an independent copy of a
693718
---------
694719
)
695720

721+
$(H3 $(LNAME2 ptr-property, `.ptr` Property))
722+
723+
$(P The `.ptr` property will give a pointer to the first element in a
724+
static or dynamic array. It may be a
725+
$(LINK2 https://en.wikipedia.org/wiki/Dangling_pointer, dangling pointer)
726+
if the array length is zero. For this reason, `.ptr` is not accessible in
727+
`@safe` code.)
728+
729+
$(P A dynamic array's `.ptr` is $(RELATIVE_LINK2 default-initialization,
730+
default-initialized) to `null`.)
731+
732+
$(P An array with zero length may have a non-null `.ptr`. That can occur:)
733+
734+
* From $(RELATIVE_LINK2 slicing, slicing) a dynamic array `a` with
735+
zero-width: `a[$..$]`.
736+
* For a zero-length static array.
737+
738+
$(SPEC_RUNNABLE_EXAMPLE_RUN
739+
---
740+
int[] a;
741+
assert(a.ptr is null);
742+
743+
int[0] z;
744+
assert(z.ptr !is null);
745+
---
746+
)
747+
696748
$(H3 $(LNAME2 resize, Setting Dynamic Array Length))
697749

698750
$(P The $(D .length) property of a dynamic array can be set
@@ -1006,7 +1058,7 @@ $(H3 $(LNAME2 default-initialization, Default Initialization))
10061058
$(LI Pointers are initialized to $(D null).)
10071059
$(LI Static array contents are initialized to the default
10081060
initializer for the array element type.)
1009-
$(LI Dynamic arrays are initialized to having 0 elements.)
1061+
$(LI Dynamic arrays are initialized to having 0 elements and a null `.ptr`.)
10101062
$(LI Associative arrays are initialized to having 0 elements.)
10111063
)
10121064

spec/function.dd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3839,6 +3839,7 @@ $(H3 $(LNAME2 safe-functions, Safe Functions))
38393839
$(LI No casting from any non-pointer type to a pointer type.)
38403840
$(LI No $(DDSUBLINK spec/expression, pointer_arithmetic, pointer arithmetic)
38413841
(including pointer indexing & slicing).)
3842+
$(LI Cannot access array $(DDSUBLINK spec/arrays, ptr-property, `.ptr` property).)
38423843
$(LI Cannot access union fields that:)
38433844
* Have pointers or references overlapping with other types
38443845
* Have invariants overlapping with other types

0 commit comments

Comments
 (0)