Reviewers: rsc, iant, r, ken2,
Message:
Hello rsc@golang.org, iant@golang.org, r@golang.org, ken@golang.org (cc:
golang-dev@googlegroups.com),
I'd like you to review this change to
https://code.google.com/p/go
Description:
spec: constant indexes and array/slice sizes must fit into int64
also:
- consistently use 'indexes' rather than 'indices'
This CL refines earlier CLs 6725053 and 6699048.
Restricting the maximum value for integer indices
to 1<<63-1 ("MaxInt64") is reasonable and permits
more compile-time checks (and a simpler implementation).
The compilers have implemented similar restrictions
early on, so this is unlikely to cause existing
programs to break.
Please review this at https://codereview.appspot.com/6899045/
Affected files:
M doc/go_spec.html
Index: doc/go_spec.html
===================================================================
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -791,8 +791,8 @@
The length of a string <code>s</code> (its size in bytes) can be
discovered using
the built-in function <a href="#Length_and_capacity"><code>len</code></a>.
The length is a compile-time constant if the string is a constant.
-A string's bytes can be accessed by integer indices 0 through
-<code>len(s)-1</code> (§<a href="#Indexes">Indexes</a>).
+A string's bytes can be accessed by integer <a href="#Indexes">indexes</a>
+0 through <code>len(s)-1</code>.
It is illegal to take the address of such an element; if
<code>s[i]</code> is the <code>i</code>'th byte of a
string, <code>&s[i]</code> is invalid.
@@ -815,12 +815,13 @@
</pre>
<p>
-The length is part of the array's type and must be a
+The length is part of the array's type; it must be a
<a href="#Constant_expressions">constant expression</a> that evaluates to
a non-negative
-integer value. The length of array <code>a</code> can be discovered
+integer value fitting into an int64: 0 <= length <=
9223372036854775807.
+The length of array <code>a</code> can be discovered
using the built-in function <a
href="#Length_and_capacity"><code>len</code></a>.
-The elements can be indexed by integer
-indices 0 through <code>len(a)-1</code> (§<a href="#Indexes">Indexes</a>).
+The elements can be addressed by integer <a href="#Indexes">indexes</a>
+0 through <code>len(a)-1</code>.
Array types are always one-dimensional but may be composed to form
multi-dimensional types.
</p>
@@ -850,8 +851,8 @@
Like arrays, slices are indexable and have a length. The length of a
slice <code>s</code> can be discovered by the built-in function
<a href="#Length_and_capacity"><code>len</code></a>; unlike with arrays it
may change during
-execution. The elements can be addressed by integer indices 0
-through <code>len(s)-1</code> (§<a href="#Indexes">Indexes</a>). The
slice index of a
+execution. The elements can be addressed by integer <a
href="#Indexes">indexes</a>)
+0 through <code>len(s)-1</code>. The slice index of a
given element may be less than the index of the same element in the
underlying array.
</p>
@@ -2498,12 +2499,20 @@
</p>
<p>
-For <code>a</code> of type <code>A</code> or <code>*A</code>
+If <code>a</code> is not a map:
+</p>
+<ul>
+ <li>the index <code>x</code> must be an integer value; it is <i>in
range</i> if <code>0 <= x < len(a)</code>,
+ otherwise it is <i>out of range</i></li>
+ <li>a <a href="#Constants">constant</a> index must not be negative and
fit into an <code>int64</code>:
+ <code>0 <= x <= 9223372036854775807</code>
+</ul>
+
+<p>
+Additionally, for <code>a</code> of type <code>A</code> or <code>*A</code>
where <code>A</code> is an <a href="#Array_types">array type</a>:
</p>
<ul>
- <li><code>x</code> must be an integer value; it is <i>in range</i> if
<code>0 <= x < len(a)</code>,
- otherwise it is <i>out of range</i></li>
<li>a <a href="#Constants">constant</a> index must be in range</li>
<li>if <code>a</code> is <code>nil</code> or if <code>x</code> is out of
range at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
@@ -2515,9 +2524,6 @@
For <code>a</code> of type <code>S</code> where <code>S</code> is a <a
href="#Slice_types">slice type</a>:
</p>
<ul>
- <li><code>x</code> must be an integer value; it is <i>in range</i> if
<code>0 <= x < len(a)</code>,
- otherwise it is <i>out of range</i></li>
- <li>a <a href="#Constants">constant</a> index must not be negative</li>
<li>if the slice is <code>nil</code> or if <code>x</code> is out of range
at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
<li><code>a[x]</code> is the slice element at index <code>x</code> and
the type of
@@ -2529,9 +2535,7 @@
where <code>T</code> is a <a href="#String_types">string type</a>:
</p>
<ul>
- <li><code>x</code> must be an integer value; it is <i>in range</i> if
<code>0 <= x < len(a)</code>,
- otherwise it is <i>out of range</i></li>
- <li>a <a href="#Constants">constant</a> index must not be negative, and
it must be in range
+ <li>a <a href="#Constants">constant</a> index must be in range
if the string <code>a</code> is also constant</li>
<li>if <code>x</code> is out of range at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
@@ -2598,7 +2602,7 @@
<p>
constructs a substring or slice. The index expressions <code>low</code> and
<code>high</code> select which elements appear in the result. The result
has
-indices starting at 0 and length equal to
+<a href="#Indexes">indexes</a> starting at 0 and length equal to
<code>high</code> - <code>low</code>.
After slicing the array <code>a</code>
</p>
@@ -2631,13 +2635,13 @@
</pre>
<p>
-For arrays or strings, the indices <code>low</code> and <code>high</code>
are
+For arrays or strings, the indexes <code>low</code> and <code>high</code>
are
<i>in range</i> if <code>0 <= <code>low</code> <= <code>high</code>
<= len(a)</code>,
otherwise they are <i>out of range</i>.
For slices, the upper index bound is the slice capacity
<code>cap(a)</code> rather than the length.
-A <a href="#Constant_expressions">constant</a> index must not be negative,
and if both indices
+A <a href="#Constant_expressions">constant</a> index must not be negative,
and if both indexes
are constant, they must satisfy <code>low <= high</code>. If
<code>a</code> is <code>nil</code>
-or if the indices are out of range at run time, a <a
href="#Run_time_panics">run-time panic</a> occurs.
+or if the indexes are out of range at run time, a <a
href="#Run_time_panics">run-time panic</a> occurs.
</p>
<p>
@@ -3359,7 +3363,7 @@
<pre>
t.Mv(7)
T.Mv(t, 7)
-(T).Mv(t, t)
+(T).Mv(t, 7)
f1 := T.Mv; f1(t, 7)
f2 := (T).Mv; f2(t, 7)
</pre>
@@ -4985,8 +4989,9 @@
<p>
The size arguments <code>n</code> and <code>m</code> must be integer
values.
-A <a href="#Constants">constant</a> size argument must not be negative, and
-if both <code>n</code> and <code>m</code> are provided and are constant,
then
+A <a href="#Constants">constant</a> size argument must not be negative and
+fit into an <code>int64</code>: <code>0 <= size <=
9223372036854775807</code>.
+If both <code>n</code> and <code>m</code> are provided and are constant,
then
<code>n</code> must be no larger than <code>m</code>.
If <code>n</code> is negative or larger than <code>m</code> at run time,
a <a href="#Run_time_panics">run-time panic</a> occurs.
@@ -4995,6 +5000,7 @@
<pre>
s := make([]int, 10, 100) // slice with len(s) == 10, cap(s) == 100
s := make([]int, 1e3) // slice with len(s) == cap(s) == 1000
+s := make([]int, 1<<63) // illegal: len(s) >
9223372036854775807
s := make([]int, 10, 0) // illegal: len(s) > cap(s)
c := make(chan int, 10) // channel with a buffer size of 10
m := make(map[string]int, 100) // map with initial space for 100 elements