| |
| Posted by Kevin Bealer in reply to Walter Bright | PermalinkReply |
|
Kevin Bealer
Posted in reply to Walter Bright
| Walter Bright Wrote:
> Kevin Bealer wrote:
> > Is the "in" operator (for AAs) safe?
>
> Good question. Andrei thinks it needs to be redesigned.
Hmmm.....
Pointers have several useful "APIs".
1. The communicate an address of an object of a particular type.
2. They can be null, which is a way to support an "optional" value.
3. They support conversion of class pointers (up and down inheritance trees).
4. They support casting to other pointer types (such as reading an int as a char[4]).
5. They support pointer arithmetic (writing malloc() like code, array indexing).
It seems like 1 and 2 are available in Java, and 3 is available but the compiler or run time code supervises the operation to make sure it looks correct. In Java, 4 and 5 are missing,
but arrays can still be indexed.
[ Off topic: A "safe" (from a memory management POV) language could allow a subset of
4 and even 5 -- you could convert an int to a char[4] or an int[10] to a char[40], or vice
versa, for example. This prevents "walking off" an array and secondary (dangling ptr)
corruption but still allows (some) clever things (like writing a limited version of malloc())
to be done.
To be "safe", you would want to prevent internal pointers -- casting int[10] to int*[10],
or to something like int[][5] (assuming int[] is struct { int* x; int length; }) should fail. ]
Getting back to the AA question, we'd like features 1 and 2 -- null or a real value. Maybe "in" should return a T[]? The ptr field is the current "in" return value, the length field is just 0 or 1. The AA structure could even contain a T[1] internally. Since array indices are always checked in safe mode, the user gets an index bounds error if they dereference it, which even seems kind of correct for an associative array -- your key is "out of bounds" by not being present...
T[] found = key in container;
: if (found) { // same as ptr syntax...
: // swap in a new value
: read_me = found[0];
: found[0] = write_me;
: } else {
: read_me = found[0]; // oops -- array bound error!
: }
(Of course, there's the backward compatibility question.)
Kevin
|