|
From: Gene on 31 Aug 2005 23:16 Seldom am I surprised by Ada semantics, but today they got me. type Int_List_Type is array(Integer range <>) of Integer; procedure Main is function F(a : Int_List_Type) return Integer is i : Integer; begin if a'Length <= 1 then return a(1); else -- calculate i s.t. 1 <= i <= a'Last -- with some algorithm; details irrelevant ... return F(a(1..i - 1) & a(i + 1, a'Last)); end if; end Calculate; a : Int_List(1..100); begin -- yada yada; fill a with values Put(Calculate(F(a))); end; The gotcha is that when (and only when) i is determined to be zero, the concatenation in the recursive call to F produces a starting index of 2 rather than 1. Of course this causes the base case test to raise an exception in the next recursive call. This is in accordance with the ALRM and GNAT implements it perfectly. Yes I know how to recode this to use a'First instead of 1 as needed. Nonetheless the rule seems silly: When a leading zero-length array is catenated to another array the result takes on the starting index of the _second_ operand. This doesn't make sense to me. Why not use the starting index of the zero-length array? Gene
From: Dmitry A. Kazakov on 1 Sep 2005 03:55 On 31 Aug 2005 20:16:43 -0700, Gene wrote: > Nonetheless the rule seems silly: When a leading zero-length array is > catenated to another array the result takes on the starting index of > the _second_ operand. This doesn't make sense to me. Why not use the > starting index of the zero-length array? Because that might be ill-defined, I guess. A more interesting question is why Empty'First does not raise any exception. After all, there is no any lower bound of an empty index range. Provided, that empty arrays are all same, of course. If not, then another interesting question would appear: how to make an empty array with the lower bound Integer'First? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Florian Weimer on 1 Sep 2005 04:02 * Dmitry A. Kazakov: > A more interesting question is why Empty'First does not raise any > exception. After all, there is no any lower bound of an empty index range. > Provided, that empty arrays are all same, of course. If not, then another > interesting question would appear: how to make an empty array with the > lower bound Integer'First? You can't. Even more problematic is the empty array whose index type is an enumeration type with just one enumeration literal.
From: Jean-Pierre Rosen on 1 Sep 2005 04:48 Gene a ýcrit : > Seldom am I surprised by Ada semantics, but today they got me. > > type Int_List_Type is array(Integer range <>) of Integer; > > procedure Main is > > function F(a : Int_List_Type) return Integer is > i : Integer; > begin > if a'Length <= 1 then > return a(1); > else > -- calculate i s.t. 1 <= i <= a'Last > -- with some algorithm; details irrelevant > ... > return F(a(1..i - 1) & a(i + 1, a'Last)); > end if; > end Calculate; > > a : Int_List(1..100); > > begin > -- yada yada; fill a with values > Put(Calculate(F(a))); > end; > > The gotcha is that when (and only when) i is determined to be zero, the > concatenation in the recursive call to F produces a starting index of 2 > rather than 1. Of course this causes the base case test to raise an > exception in the next recursive call. This is in accordance with the > ALRM and GNAT implements it perfectly. > > Yes I know how to recode this to use a'First instead of 1 as needed. > > Nonetheless the rule seems silly: When a leading zero-length array is > catenated to another array the result takes on the starting index of > the _second_ operand. This doesn't make sense to me. Why not use the > starting index of the zero-length array? > Because the lower bound of a null array needs not belong to the subtype used for indexing. Note that you can force the lower bound by subtype conversion: declare Result : constant string := F(a(1..i - 1) & a(i + 1, a'Last)); subtype Force_Lower_To_1 is string (1 .. Result'length); begin return Force_Lower_To_1 (Result); end; -- --------------------------------------------------------- J-P. Rosen (rosen(a)adalog.fr) Visit Adalog's web site at http://www.adalog.fr
From: Georg Bauhaus on 1 Sep 2005 07:42
Dmitry A. Kazakov wrote: > A more interesting question is why Empty'First does not raise any > exception. Because 'First does not denote an element? > After all, there is no any lower bound of an empty index range. ? What's the bound of a range? (as opposed to a bounded array) > Provided, that empty arrays are all same, of course. If not, then another > interesting question would appear: how to make an empty array with the > lower bound Integer'First? Carrying the arguement further, how to reference an element outside the machine's storage? |