From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!news.unit0.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: ADA.STRINGS.INDEX_ERROR : a-strunb.adb:782 Date: Mon, 15 Jan 2018 05:23:30 +0200 Organization: Tidorum Ltd Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net w4NA6EiXuTlwwM6j7UvmXwk8GpaQNzxom9l8VL2GduorXzWVgU Cancel-Lock: sha1:3L416YM3uYYIBAMnCpHXkCd3h8Q= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 In-Reply-To: Xref: reader02.eternal-september.org comp.lang.ada:49901 Date: 2018-01-15T05:23:30+02:00 List-Id: On 18-01-15 03:18 , Mehdi Saada wrote: > This if statement exactly, seems to raise > "ADA.STRINGS.INDEX_ERROR : a-strunb.adb:782"(No indication of line, so I can't know more). > What does this exception means ? That you have tried to access a non-existent element of some kind of string (Bounded or Unbounded). Note that Ada.Strings.Bounded and Ada.Strings.Unbounded are both children of Ada.Strings, where this exception is declared, and both use this exception. > You can see there's no string type variable to be accessed, here. > CHAINE is of UNBOUNDED_STRING type. > LA_PILE is a stack of characters, > EMPILER means "putting on the stack's top" in french. > > if IS_BASIC(ELEMENT(CHAINE,IND)) then The exception probably comes from the above call of ELEMENT. > EMPILER(LA_PILE,ELEMENT(CHAINE,IND)); > else DELETE(CHAINE, IND,IND); > end if; > > It's enclosed in: > for Ind in 1..Length(CHAINE) loop Note that the iteration range, 1 .. Length(CHAINE), is computed here using the value of CHAINE at the *start* of the loop, and is not recomputed during the execution of the loop. > begin > if IS_BASIC(ELEMENT(CHAINE,IND)) then > EMPILER(LA_PILE,ELEMENT(CHAINE,IND)); > else DELETE(CHAINE, IND,IND); This DELETE shortens CHAINE. If it occurs one or more times during the iteration of the loop, before the last iteration of the loop, then at some later iteration the index Ind will be larger than the (new) Length(CHAINE), and the exception results. > end if; > end; > end loop; To fix this error, you must make the loop recompute Length(CHAINE) when needed, for example in this way: for Ind in 1 .. Length(CHAINE) loop exit when Ind > Length(CHAINE); if IS_BASIC ... ... end if; end loop; However, I would write it like this, to avoid the confusion of a double check of Length(CHAINE): Ind : Positive := 1; ... while Ind <= Length(CHAINE) loop if IS_BASIC ... ... end if; Ind := Ind + 1; end loop; Note that in the "while" loop, the condition (Ind <= Length(CHAINE)) is evaluated on every loop iteration. In a "for" loop, the index range is evaluated once, at the start of the loop. However, I suspect that there is a deeper error in your loop, related to the DELETE. Consider what happens if CHAINE is, say, "ABCDEFG", and the DELETE occurs for the first time when Ind = 3, at CHAINE(Ind) = 'C'. When you DELETE(CHAINE, 3, 3), CHAINE becomes "ABDEFG". On the next loop iteration, Ind = 4, which means the loop checks CHAINE(4) = 'E'. The letter 'D', which used to be CHAINE(4) but is now CHAINE(3), is not checked. Do you really need to DELETE in the loop? If you do, then you must take into account that DELETE renumbers the elements of CHAINE after the deleted character. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .