Array Lower Bounds

bearophile bearophileHUGS at lycos.com
Tue Dec 18 05:43:24 PST 2007


Mike Marquard:
> I know the default starting index for arrays is zero in D. But is there any way you can change the lower bounds to something other zero? For instance having the index go from 1 to 10 or say 100 to 200.

Delphi, TurboPascal, and probably FreePascal have such feature, and once in a while it's useful, see here for example:
http://blogs.warwick.ac.uk/mtcharemza/entry/fortran_9095_versus_1
but it's not difficult to adapt your mind to the fixed 0 starting point, and you don't need to go looking at definition of the array type every time to see what's the actual starting point of the array you want to use.
If you want to simulate something like that in C (and D) you may do something like the following, but I don't like this solution much, it's probably better to just use the 0 starting point (note that with -release the asserts go away, and -inline does its work, removing the call to bounds() too):

import std.stdio: writef, writefln;
import std.string: format;

long bounds(long i, long start, long len) {
  // assert doesn't string-ify all successive arguments yet
  assert(i >= start, format("%d < %d", i, start));
  assert(i < start + len, format("%d >= %d + %d", i, start, len));
  return i;
}

void main() {
  const N = 10;
  const SHIFT = 5;

  int[N] a;
  foreach(i, ref el; a)
    el = i;

  typeof(a[0])* b = a.ptr - SHIFT;
  for(int i = 0; i < N; i++) {
    writef(b[bounds(i+SHIFT, SHIFT, a.length)], " ");
    b[bounds(i+SHIFT, SHIFT, a.length)] = i * 10;
  }
  writefln();

  writefln(a);

  // speed benckmark ----------------------
  uint arr[1_000];
  for(uint j; j < 30_000; ++j)
    for(uint i; i < arr.length; ++i) {
      // With -release -O -inline they run in equal time
      static if (true) // change this
        arr[i] = i;
      else
        arr[bounds(i, 0, arr.length)] = i;
    }
}

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list