comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Normalizing array indices
Date: Fri, 28 Oct 2011 16:13:58 -0500
Date: 2011-10-28T16:13:58-05:00	[thread overview]
Message-ID: <j8f5up$cg5$1@munin.nbi.dk> (raw)
In-Reply-To: Pine.LNX.4.64.1110282013540.21821@medsec1.medien.uni-weimar.de

<Stefan.Lucks@uni-weimar.de> wrote in message 
news:Pine.LNX.4.64.1110282013540.21821@medsec1.medien.uni-weimar.de...
> Hi all, does anyone know a way to change the array indices of a subprogram
> parameter to start with a default index? This question occurred to me when
> I happened to discover a subtle bug in a sort procedure I had implemented.
>
>  generic
>    type Element_Type is private;
>    type Sort_Array_Type is array (Positive range <>) of Element_Type;
>    with function "<" (Left, Right: Element_Type) return Boolean is <>;
>  procedure Sort(A: in out Sort_Array_Type);
>
> I had a reasonable amount of black box tests and Sort passed all of them.
>
> Some time later, I added a test with A'range being
>   Positive'Last -2 .. Positive'Last
> and boooom -- got a Constraint_Error. As it turned out, there was a
> Positive index variable which could take the value A'Last+1 -- which is
> perfectly OK except when A'Last = Positive'Last.

This is pretty typical. We've often talked about the need in Ada for 
one-sided array subtypes, but we don't have any first class ones at this 
point.

I probably would constrain the parameter to have a lower bound of 1. Using 
Ada 2012:

generic
   type Element_Type is private;
   type Sort_Array_Type is array (Positive range <>) of Element_Type;
   with function "<" (Left, Right: Element_Type) return Boolean is <>;
procedure Sort(A: in out Sort_Array_Type)
   with Pre => A'First 1;

You could do something similar with a subtype using a dynamic predicate (but 
not in a generic specification).

In Ada 2005 and earlier, I'd simply make it part of the spec with some 
English wording, and then start the code with
    if A'First /= 1 then raise Program_Error; end if;
(You could also use pragma Assert if you don't mind the possibility that 
someone turned it off.)

Then, if you had any calls that don't have the right bounds (which is likely 
to be rare), I'd use a sliding trick similar to the one Adam showed. (But 
I'd probably try hard to figure out how to avoid passing the slice in the 
first place.)

Of course, it's better to make the routine work for all possible bounds. And 
if you do that, you certainly need to add that to the testing burden (it's 
commonly forgotten and probably is one of the most common Ada bugs).

                                           Randy.





  parent reply	other threads:[~2011-10-28 21:16 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-28 18:58 Normalizing array indices Stefan.Lucks
2011-10-28 20:36 ` Adam Beneschan
2011-11-01 20:18   ` Stefan.Lucks
2011-10-28 21:13 ` Randy Brukardt [this message]
2011-10-29  7:29   ` Pascal Obry
2011-10-29 19:18     ` Jeffrey Carter
2011-10-29 19:58       ` tmoran
2011-10-29 21:15         ` Simon Wright
2011-10-29 20:41       ` Randy Brukardt
2011-11-01 20:49         ` stefan-lucks
2011-11-01 20:44     ` stefan-lucks
2011-11-01 20:43   ` stefan-lucks
2011-11-02 12:16     ` Robert A Duff
2011-10-29  9:05 ` Simon Wright
2011-10-29  9:23   ` Dmitry A. Kazakov
2011-11-01 20:55   ` stefan-lucks
2011-11-02 12:14   ` Robert A Duff
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox