comp.lang.ada
 help / color / mirror / Atom feed
* Emulating Modula-3's FOR loop
@ 1996-07-07  0:00 David J. Fiander
  1996-07-07  0:00 ` Robert Dewar
  0 siblings, 1 reply; 2+ messages in thread
From: David J. Fiander @ 1996-07-07  0:00 UTC (permalink / raw)



I just ran across something minor, but annoying.  Suppose I've
got an array, indexed by the type Subscript, and I want to
operate on every n'th element of the array.  In Modula-3, I'd say
something like

	FOR i FROM n TO last BY n do
	    (* process the array elements *)
	END;

Now, if last is not divisible by n, this will still work, without
raising a Constraint_Error (or the modula equivalent).  But in
Ada, the obvious translation

	procedure Operate(Arr: in out Array(Subscript) of Elt;
			  N: in Subscript) is
	    I: Subscript := N;
	begin
	    while I <= Subscript'Last loop
	        -- Process the array
	        I := I + N;
	    end loop;
	end Operate;

will raise a Constraint_Error on the last addition.  Is there a
better way to deal with this than

	...
	begin
	    while I <= Subscript'Last loop
	        -- process
	        I := I + N;
	    end loop;
	exception
	    when Constraint_Error => null;
	end;





^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Emulating Modula-3's FOR loop
  1996-07-07  0:00 Emulating Modula-3's FOR loop David J. Fiander
@ 1996-07-07  0:00 ` Robert Dewar
  0 siblings, 0 replies; 2+ messages in thread
From: Robert Dewar @ 1996-07-07  0:00 UTC (permalink / raw)



David J. Fiander suggests for a loop jumping by N:

        begin
            while I <= Subscript'Last loop
                -- process
                I := I + N;
            end loop;
        exception
            when Constraint_Error => null;
        end;

This is definitely bad code. Using Constraint_Error to catch normal
flow of control situations as opposed to errors is a bad misuse of
the feature. Not only is it conceptually incorrect, but in practice
it can be disastrously inefficient (in many implementations, a
constraint error signal will involve a kernel trap with huge overhead).

A much better translation is

      loop
         -- process

         exit when I > Subscript'Last - N;
         I := I + N;
      end loop;

this should generate perfectly efficient code, since the expression
Subscript'Last - N is loop invariant. Note that this assumes you know
the loop will execute at least once. if not, the entire loop needs
to be protected by an appropriate test.





^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1996-07-07  0:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-07-07  0:00 Emulating Modula-3's FOR loop David J. Fiander
1996-07-07  0:00 ` Robert Dewar

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