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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!elroy.jpl.nasa.gov!swrinde!zaphod.mps.ohio-state.edu!samsung!think.com!linus!linus!linus!mbunix!eachus From: eachus@aries.mitre.org (Robert I. Eachus) Newsgroups: comp.lang.ada Subject: Re: Reference vs. copy semantics in passing parameters Message-ID: Date: 19 Feb 91 19:00:38 GMT References: <5572@baird.cs.strath.ac.uk> <1991Feb13.211643.25777@rti.rti.org> <2725@sparko.gwu.edu> <2742@sparko.gwu.edu> <1991Feb18.141058.1@elcgl.epfl.ch> Sender: news@linus.mitre.org (News Service) Organization: The Mitre Corp., Bedford, MA. In-Reply-To: madmats@elcgl.epfl.ch's message of 18 Feb 91 13:10:58 GMT Nntp-Posting-Host: aries.mitre.org List-Id: In article <2742@sparko.gwu.edu>, mfeldman@seas.gwu.edu (Michael Feldman) writes: > > PS: It seems to me that Ada9x could clarify the issue by simply requiring > that structured parameters be passed by reference (instead of the Ada83 > rule that it's implementation-dependent). Since a program whose behavior > depends upon the method of passing is - by definition of the LRM - > erroneous, the only programs that would break would be erroneous ones, > which Ada9x says it doesn't care about. So the clarification would be > upward compatible. Ada9x-ers: what would be the objections? There are two other reasons for allowing arrays to be passed by copy: descriptors and slices. For example, if I pass a STRING to a Text_IO routine, it will almost certainly require a descriptor be passed also. However, if I declare a constrained sting type: type MyString is array (Integer range 1..10) of Standard.Character; Then no descriptor is required to call: procedure FOO(S: in MyString); So far so good, but now let us declare a record type with no room for descriptors: type MyRec is record S: String(1...10); end record; for MyRec'SIZE use 80; MR: MyRec := (S => "Try this.."); Now we call Text_IO.Put_Line(MR). Where does the descriptor come from? The easy solution is to make this call by copy, and generate a descriptor for the area copied to. A similar problem occurs if an array is packed as part of a record--unpacking produces a copy. As for slices try: type Bit_Array is array (Integer range <>) of Boolean; pragma PACK(Bit_Array); X: Bit_Array(1..1000) := (others => FALSE); Now how do you handle X(2..11) := X(30..39) and X(100..109); ? Most compilers will copy the slices so that the copies begin on byte or word boundaries rather than impose the overhead of bit level pointers on all subprograms which have parameters of such types. (This way you only incur the cost when you use such a feature, and in the above example the generated code will probably be much more efficient in the pass by copy case. Notice that in both cases the decision as to whether to pass by copy or by reference is made when the call is compiled not when the subprogam itself is compiled. This is the reason for the standard warning that the compiler is allowed to change the parameter passing mechanism from call to call, and even from one invocation to the next. For example, in the bit slice example, if you have: X(A..B) := X(C..D) and X(E..F); the generated code might call a run-time routine which will makes a copy only when A, C or E is not a multiple of eight, so on a particular call one parameter might be passed by copy and the other by reference. -- Robert I. Eachus Our troops will have the best possible support in the entire world. And they will not be asked to fight with one hand tied behind their back. President George Bush, January 16, 1991