negative lengths and reverse pointers

Bill Baxter wbaxter at gmail.com
Fri Oct 20 09:58:40 PDT 2006


Reiner Pope wrote:
> Ameer Armaly wrote:
> 
>> Hi all.  After thinking about foreach_reverse and arrays, a rather 
>> strange idea hit me: what if we had reverse arrays, where whenever you 
>> tried to access an element it would go backwards instead of forwards 
>> in a memmory block to find it?  This could be indicated by a negative 
>> length; if length is negative, the pointer points to the end of the 
>> memmory chunk as opposed to the beginning.  When you assign a negative 
>> length, all the compiler would have to do is find the endpoint of the 
>> positive version of the length you gave it and set the pointer to 
>> point to that.  This way array.reverse simply = array.length * -1, 
>> which would allow you to go through an array backwards with much more 
>> efficiency.  Kind of random, but might be useful; ideas?
>>
> This would be allowed by Norbert Nemec's strided arrays proposal (it's 
> for multidimensional arrays, but it can also be useful for 1-dimensional 
> arrays). This can indeed be a powerful feature, and his proposal milks 
> that power, while syntactically separating strided arrays from normal 
> arrays to avoid the overhead of checking the stride (which is equivalent 
> to checking whether the length is negative in your example).
> 
> Cheers,
> 
> Reiner

Good point.  In fact as I was responding about the -length idea, I was 
thinking to myself, "I think that's possible with Numpy's strided 
arrays..." which is where Norbert took most of the ideas for the above 
proposal.  (Or maybe Norbert was one of the creators of Numpy/Numeric?)

Anyway, if you want to write a function that deals with the data in a 
numpy array at the raw memory level, you have two options:

1) get the stride values and use those in all your indexing operations. 
  So if we're talking 1D arrays only, something like:
     for (i=0; i<array.length; i++) {
        val_i = *(array.base_ptr + i*array.stride);
     }

2) or you call a function that 'normalizes' the layout.  If the array is 
in standard order, it's a no-op.  Otherwise it returns you a copy of the 
data in the standard form.
     base_ptr = normalize(array) // may or may not == array.base_ptr
     for (i=0; i<array.length; i++) {
         val_i = base_ptr[i];
     }

It's very flexible and powerful, especially when you start talking about 
N-dimensional arrays.  But there is a bit of overhead with always having 
to compute addresses wrt the stride value.

--bb



More information about the Digitalmars-d mailing list