jon@bdmrrr.bdm.com (Jon Humphreys) (06/21/89)
I'm currently trying to learn Ada by translating a program written in BASIC (my employer's choice, not mine), and I've got a fairly fundamental question: when passing parameters from one package to another, is it possible to simulate something like a FORTRAN common block by placing variables in a package and then using the package whenever I need to access/modify the variables? For example, consider the following hierarchy: main | -------------------- | | A B ---|--- | | (B, C, and D are a package) C D If a set of variables were used in procedures A and D, would it be possible to create a package containing these variables and then include them in procedure A and D? Or should all the variables be declared in main and then passed as parameters to A and B, and then from B to D (this seems inefficient)? I guess what I'm asking is, which way would be considered correct in Ada? (Currently, we don't even have a compiler, so there isn't any way for me to test this kind of thing.) Thanks for any help, jon
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe,2847,) (06/22/89)
From article <1116@bdmrrr.bdm.com>, by jon@bdmrrr.bdm.com (Jon Humphreys): > I'm currently trying to learn Ada by translating a program written > in BASIC (my employer's choice, not mine), and I've got a fairly > fundamental question: when passing parameters from one package > to another, is it possible to simulate something like a FORTRAN > common block by placing variables in a package and then > using the package whenever I need to access/modify the variables? Sure, it's easy. Just set up: package Global_Variables is First_Variable : First_Variable_Type := Initial_Value; Second_Variable : Second_Variable_Type; -- etc... end Global_Variables; Then simply with the package whenever you need it; just remember to qualify all references with the package name, e.g., Global_Variables.First_Variable := whatever...; Now as to whether or not this is a good idea, I think *you* already know that the application should be redesigned rather than translated literally; so just post your boss's e-mail address and we'll... :-) Bill Wolfe, wtwolfe@hubcap.clemson.edu
stt@inmet.inmet.com (06/27/90)
Re: Assumptions about parameter passing No, it is not a safe assumption. In a distributed address space (such as the 1750A expanded memory model), the compiler will copy composite parameters which would not be addressible in the called routine's address space, whereas those which are addressible may be passed by reference. Another case is where one formal parameter is constrained, and the other is unconstrained or simply has a different constraint (though both are of the same type). Many compilers pass "short" composite objects by copy, and longer or unconstrained ones by reference. In any case, I am curious why you care. It would be useful to have specific examples of where this kind of assumption about parameter passing would be useful, since limiting compiler flexibility can severely interfere with efficiency. However, it is also the case that variability can make certain kinds of program proofs more complicated (though not always! Sometimes it is easier to prove something using a non-deterministic model than a deterministic model). S. Tucker Taft Intermetrics, Inc. Cambridge, MA 02138
mfeldman@seas.gwu.edu (Michael Feldman) (06/28/90)
In article <1569@oravax.UUCP> davidg@oravax.UUCP (David Guaspari) writes: >Certain kinds of reasoning about Ada subprograms that terminate by >raising exceptions are considerably simplified if one is allowed to >make the following assumption: > > If a and b are actual parameters to some call of subprogram P, > and a and b are of the same type, then that call passes them > in the same way (either both by copy or both by reference). Scalars are passed by copy - always. Structures and arrays can be passed by reference or by copy. I can speak for a few compilers I know (but don't remember which is which) - many systems will gauge which way to pass based on the size of the parameter. That is, arrays known to be "small" will be copied, but arrays not known to be small - either known to be large, or unconstrained and of unknown size - will be passed by reference. Since constrained objects of an unconstrained type have different subtypes but the same type, what you say holds true in my experience. I can't imagine why different objects of the same type should be passed differently. But then again, there are a lot of imaginable things _I_ can't imagine. Great question for language lawyers! --------------------------------------------------------------------------- Prof. Michael Feldman Department of Electrical Engineering and Computer Science The George Washington University Washington, DC 20052 +1-202-994-5253 mfeldman@seas.gwu.edu ---------------------------------------------------------------------------
davidg@oravax.UUCP (David Guaspari) (06/29/90)
Here's why I asked whether it would be reasonable to assume that parameters of the same type are passed in the same way. My problem is reasoning about the values of out or inout parameters of composite types after exceptional exit. There are useful, simple cases in which we know how to write the intended programs (in a natural way) and convince ourselves that they're correct. 1. Example: Consider procedure add_item(comp: in out composite_type, i: item_type) part of whose specification is If i is an inappropriate item, then raise the exception INAPPROPRIATE_ITEM and leave comp unchanged. If comp is passed by copy, then this part of the specification is satisfied free of charge, so (at least as far as the given spec is concerned) we can safely reason about add_item under the assumption that comp is passed by reference. 2. Generalizing the example: What the example really shows is that it's possible to reason easily about *invariant properties* of writable composite parameters -- i.e., about specifications like (*) If some_exception is raised then (in the resulting exit state) comp still satisfies some_property_it_satisfied_on_entry It takes modest care to formulate "comp still satisfies ..." correctly. 3. Generalizing too far: I'm involved in designing a specification language for Ada programs. It permits you to say things like (*), but not to state any other kinds properties of the value of comp upon exceptional exit. Naturally, we want the class of permitted invariant properties to be as general as possible (so long as we can still reason about them easily). Under Ada's rules, we're going too far if we permit the invariant to be a joint property of two writable parameters, e.g. (for the case in which composite_type is an array type (or, in the second case, an array type with discrete components)) if comp1 and comp2 are permutations of one another upon entry, then they are still permutations of one another upon exceptional exit or the lexicographic ordering of comp1 and comp2 is the same on exceptional exit as it was on entry For specifications like these, we can safely pretend that comp1 and comp2 are passed by reference only if we are entitled to assume that they're passed by the same mechanism. Hence my question. David Guaspari oravax!davidg@cu-arpa.cs.cornell.edu davidg%oravax.uucp@cu-arpa.cs.cornell