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=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,da5197b9dca0ed40 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Processing array subsections, a newbie question. Date: Sun, 13 Jun 2010 09:28:16 +0300 Organization: Tidorum Ltd Message-ID: <87jc41FftrU1@mid.individual.net> References: <4c13db30$0$2391$4d3efbfe@news.sover.net> <8739wsottd.fsf@ludovic-brenta.org> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net k6hhHDh96YURhA9zjdLx2wc0wuhlqEKE5QpIetx1d9cYSYjJlj Cancel-Lock: sha1:d009/6+BeSPj35ztE5cFDuxNc8k= User-Agent: Mozilla-Thunderbird 2.0.0.24 (X11/20100328) In-Reply-To: <8739wsottd.fsf@ludovic-brenta.org> Xref: g2news1.google.com comp.lang.ada:11671 Date: 2010-06-13T09:28:16+03:00 List-Id: Ludovic Brenta wrote: > "Peter C. Chapin" writes: >> Ok : Boolean := True; >> Index_Fst : Natural := Buffer'First; >> Index_Lst : Natural; >> ... >> >> while Ok and Index_Fst <= Buffer'Last loop >> Do_Something(Buffer, Index_Fst, Index_Lst, Ok); >> Index_Fst := Index_Lst + 1; >> end loop; >> >> The problem with this code is that the assignment to Index_Fst inside the loop >> might raise Constraint_Error if Index_Lst = Buffer'Last after Do_Something >> finishes. I can work around this problem but my solutions tend to be rather >> ungainly looking. Surely there must be an easy way to handle this. Constraint_Error would be raised only if Index_Lst = Natural'Last after Do_Something. By subtyping the index type of Buffer you could ensure that Buffer'Last < Natural'Last, which would avoid the risk of Constraint_Error. (Perhaps this is the ungainly work-around that you mention.) > How about: A few nitpicks on Ludovic's suggestion: > Ok : Boolean := True; The initial value for Ok is unneccessary, as Do_Something will assign Ok before it it used. > Index_Fst : Natural := Buffer'First; > Index_Lst : Natural; > ... > loop > Do_Something(Buffer, Index_Fst, Index_Lst, Ok); In this call of Do_Something, Index_Fst may not be a valid index for Buffer, since there is no preceding check that Index_Fst <= Buffer'Last, as there was in the original while-loop. But perhaps it is known, in the original context, that Buffer is not empty. > exit when not Ok; > exit when Index_Fst = Buffer'Last; For robustness I would write Index_Fst >= Buffer'Last. (Perhaps this could also help some SPARK range analysis.) > Index_Fst := Index_Lst + 1; > end loop; So my suggestion is: Ok : Boolean; Index_Fst : Natural := Buffer'First; Index_Lst : Natural; ... if Index_Fst <= Buffer'Last then -- Buffer is not empty, something to be done. loop Do_Something(Buffer, Index_Fst, Index_Lst, Ok); exit when not Ok; exit when Index_Fst >= Buffer'Last; Index_Fst := Index_Lst + 1; end loop; else -- Buffer is empty. ... end if; -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .