[Nickle] About arrays and things
Bart Massey
bart at cs.pdx.edu
Mon Jun 30 02:47:49 PDT 2003
This is an attempt to summarize a long talk Keith and I had
about Nickle semantics, esp about arrays. The following
statements are true as of June 28, 2003.
+ Nickle assignment is by "rebinding with
copied value". If I say
int[3] x = {1,2,3};
int[3] y = {4,5,6};
x = y;
the third line will make the storage location x have a
fresh copy of the array at storage location y; the old
x array is not altered by this operation, although it
can no longer be referenced.
+ The size is not part of the type. Thus, I can currently
say
string[1] a = (string[2]){};
without error: the array dimensions are deleted without
examining them. The only time that the array dimensions
currently matter are in certain kinds of initializations
such as
string[3] a = {"x" ...};
where they are used to determine the size of the
implicitly allocated fresh array. The synonym "*"
can and should be used where size doesn't matter, e.g.
int f(int[3] a) {
...
is bad style since the 3 in the parameter declaration
will never be checked.
+ Nickle arrays are fully bounds-checked.
+ Nickle has "const" declarations, that correspond to
globally-allocated storage that must be initialized in
its definition.
In the new world as of June 31, several things will have
changed:
+ Array sizes are still not part of their static type:
they cannot be, since they are not in general statically
computable.
+ Arrays sizes become part of the dynamic type system.
Thus e.g. the parameter passing example above becomes
checked.
+ There are two kinds of values of array type: growable
arrays and fixed arrays. A growable array has no upper
bounds check on stores: storing into an "off-the-end"
location causes that location and all intervening
locations to suddenly spring into existence.
int[*] x;
x[1] = 0;
assert(dim(x) == 2, "bad dim");
A fixed array is defined using integer subscript or
the new array operator [...]. Growable arrays are
defined using the array operator [*] as above. (Yes,
this is completely wrong-headed: * should be fixed and
... should be variable---bug Keith about fixing it.)
+ Growable arrays can be sized arbitrarily using the
setdim() and setdims() functions, which are analogous
to dim()/dims():
setdim(&x, 2);
+ The sizing expression in an array declaration need not
be constant. This brings up some serious issues with
typedef. Consider
{
int i = 3;
typedef int[i] t;
t a1 = {1,2,3};
i = 4;
t a2 = {1,2,3,4};
...
Should this last assignment work or not? It probably
depends on whether one views the i in the typedef to be
bound at type-def time, or at type-use time. Nickle
chooses the latter view. Like Nickle constants, Nickle
array dimensioning values in typedefs are expressions
evaluated with global lifetime. Thus, the last line is
illegal.
+ Note that for array definitions without typedef, the
subscript expression is evaluated with the same lifetime
as the array itself.
Enough for tonight: more tomorrow.
Bart
More information about the Nickle
mailing list