* ADA Compiling Query @ 1991-02-11 15:06 Gordon Russell 1991-02-12 19:01 ` Michael Feldman ` (2 more replies) 0 siblings, 3 replies; 19+ messages in thread From: Gordon Russell @ 1991-02-11 15:06 UTC (permalink / raw) Hi out there, I am hoping that someone on the network can answer a compiler implementation problem for me. The problem stems from my PhD research into compiler techniques. If we consider the following program extract... variable1 : integer; procedure MAIN is variable1 : integer; result : integer; ---------------------------------------------------- procedure GET_RESULT(variable2: in out integer) is begin variable1=2; variable2=variable1 + variable2; end GET_RESULT; ---------------------------------------------------- begin variable1=10; get_result(variable1); end MAIN; My question is.......what is variable1 equal to at the end of MAIN? There appears to be a number of options....either (1) 4 (2) 12 (3) Something wierd (4) Compiler dependent. Evidentally, it is reliant on whether GET_RESULT operates on variable2 directly or indirectly. I am hoping that the results are compiler dependent. Does anyone have an ADA compiler who is willing to test this? I am especially interested to hear from official sources (if they are reading this), since I do not want to break any validation suite program. Reply either to this newsgroup or by email. I will post a concensus if comments are mailed directly to me. Please no flames if this program is not syntatically correct, as it is the mechanism which I am inquiring after. And yes, I do think that this is poor programming practice, but when has that stopped anyone! Thanx in advance.....Gordon Russell gor@cs.strath.ac.uk [I would expect that a look at the standard would answer this question quickly. The issue of call by reference vs. call by copy in/copy out is at least 30 years old. Algol 60 inadvertently introduced call by name which forced situations like this to compute the answer 4. The various Fortran standards have remained resolutely ambiguous, leaving the interpretation up to the compiler writer. The "in out" syntax suggests that copy in/copy out is expected, but what the syntax suggests and what the standard says are of course entirely different things. -John] -- Send compilers articles to compilers@iecc.cambridge.ma.us or {ima | spdcc | world}!iecc!compilers. Meta-mail to compilers-request. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: ADA Compiling Query 1991-02-11 15:06 ADA Compiling Query Gordon Russell @ 1991-02-12 19:01 ` Michael Feldman 1991-02-13 21:16 ` Jeff Bartlett 1991-02-18 14:33 ` ADA Compiling Query stt 2 siblings, 0 replies; 19+ messages in thread From: Michael Feldman @ 1991-02-12 19:01 UTC (permalink / raw) In article <5572@baird.cs.strath.ac.uk> Gordon Russell <gor@cs.strath.ac.uk> writes: > >procedure MAIN is > variable1 : integer; > result : integer; >---------------------------------------------------- > procedure GET_RESULT(variable2: in out integer) is > begin > variable1=2; > variable2=variable1 + variable2; > end GET_RESULT; >---------------------------------------------------- > begin > variable1=10; > get_result(variable1); > end MAIN; Please don't take this as a flame, Gordon; I'm posting it for others' use as well. The critique is not of the syntax errors, nor of the fact that this classical aliasing problem is poor style (which you point out), but the fact that the answer to this question is readily available in the LRM, namely sect. 6.2, in which it states quite clearly that this parameter is passed by copy-in/copy-out. This means that GET_RESULT is working on a local copy of variable1 (in its alias as variable2). For a _scalar_ parameter, the parameter semantics is well-defined. For a parameter of a _composite_ type, it's not: the implementation can choose copy-in/copy-out _or_ reference passing. This would have made your question more interesting. Here's an exercise I give to my classes, when we discuss this stuff: for some compiler you have access to, prove that the scalar passing is by value/result (aka copy-in/copy-out), and write programs to demonstrate the behavior of passing for composite types. Hint: most compilers use reference passing for large arrays (common sense, no?); some use value/result for small arrays. If the latter, find the "crossover". [This exercise is to create a _purposely_ erroneous program: we _want_ its behavior to depend on the mechanism :-)] <WARNING: SERMON COMING> The LRM is really a good source of information. Serious Ada folks should have it and use it. <HERE ENDETH THE SERMON> Mike Feldman -- Send compilers articles to compilers@iecc.cambridge.ma.us or {ima | spdcc | world}!iecc!compilers. Meta-mail to compilers-request. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: ADA Compiling Query 1991-02-11 15:06 ADA Compiling Query Gordon Russell 1991-02-12 19:01 ` Michael Feldman @ 1991-02-13 21:16 ` Jeff Bartlett 1991-02-14 16:45 ` Michael Feldman 1991-02-18 14:33 ` ADA Compiling Query stt 2 siblings, 1 reply; 19+ messages in thread From: Jeff Bartlett @ 1991-02-13 21:16 UTC (permalink / raw) In article <5572@baird.cs.strath.ac.uk>, gor@cs.strath.ac.uk (Gordon Russell) writes: > [ does Ada pass arguments by reference or copy in/copy out?] See ANSI/MIL-STD-1815A section 6.2 paragraph 7: .... The language does not define which of these two mechanisms is to be adopted for parameter passing, nor whether different calls to the same subprogram are to use the same mechanism. The execution of a program is erroneous if its effect depends on which mechanism is selected by the implementation. And section 1.6 paragraph 6: (c) Erroneous execution. The language rules specify certain rules to be obeyed by Ada programs, although there is no requirement on Ada compilers to provide either a compilation-time or run-time detection of the violation of such rules. .... The effect of erroneous execution is unpredictable. Jeff Bartlett Center for Digital Systems Research Research Triangle Institute jb@rti.rti.org mcnc!rti!jb (919)-541-6945 -- Send compilers articles to compilers@iecc.cambridge.ma.us or {ima | spdcc | world}!iecc!compilers. Meta-mail to compilers-request. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: ADA Compiling Query 1991-02-13 21:16 ` Jeff Bartlett @ 1991-02-14 16:45 ` Michael Feldman 1991-02-15 23:09 ` Jim Showalter 0 siblings, 1 reply; 19+ messages in thread From: Michael Feldman @ 1991-02-14 16:45 UTC (permalink / raw) In article <1991Feb13.211643.25777@rti.rti.org> jb@rti.rti.org (Jeff Bartlett) writes: >In article <5572@baird.cs.strath.ac.uk>, gor@cs.strath.ac.uk (Gordon Russell) writes: > >See ANSI/MIL-STD-1815A section 6.2 paragraph 7: > > .... The language does not define which of these two mechanisms is to > be adopted for parameter passing, nor whether different calls to the > same subprogram are to use the same mechanism. The execution of a > program is erroneous if its effect depends on which mechanism is > selected by the implementation. > C'mon, guys - a little precision please. This applies only to _structured_ parameters. The preceding paragraph (6) states clearly that _scalars_ are copied. I've bumped into a lot of Pascal folks learning Ada who think that passing an array as IN OUT will magically get it passed by reference. This is a trick used in Pascal - you pass an array as VAR even if it is being used as an input parameter, because the _Pascal_ standard requires that it be copied otherwise. This sticks you in a bind in Pascal, because you've turned an input parameter into something your procedure may inadvertently modify. So you've traded speed for reliability. Too bad, but this is what Prof. Wirth wanted. (It's carried over to Modula-2 also). Carrying the Pascal trick over to Ada is futile and unnecessary. An IN parameter _cannot_ be modified; the compiler won't allow it. This permits the implementer to pass an array (yes, even as an IN parameter) by reference to save copying time and space. As I said in a previous posting, most implementers will pass by reference any structure large enough to be of concern. But if you think that using the Pascal trick - artificially making the array IN OUT to _guarantee_ that it'll be passed by reference - will work, guess again. Mike Feldman ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: ADA Compiling Query 1991-02-14 16:45 ` Michael Feldman @ 1991-02-15 23:09 ` Jim Showalter 1991-02-17 0:19 ` Reference vs. copy semantics in passing parameters Michael Feldman 0 siblings, 1 reply; 19+ messages in thread From: Jim Showalter @ 1991-02-15 23:09 UTC (permalink / raw) There is an unsafe aspect of passing access types as IN parameters in Ada that is, sad to say, handled rather better in C++. In Ada, you can pass an access type to a function as an IN: type Some_Foo... type Pointer is access Some_Foo; function Some_Bar (Some_Param : in Pointer)... And then, inside the function, dereference the pointer and modify the pointed-to construct. In C++, you can declare not only the pointer constant but the pointed to construct constant as well. This allows passing by reference in a read-only manner, which is NOT possible in Ada at present. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Reference vs. copy semantics in passing parameters 1991-02-15 23:09 ` Jim Showalter @ 1991-02-17 0:19 ` Michael Feldman 1991-02-17 18:54 ` Erland Sommarskog ` (3 more replies) 0 siblings, 4 replies; 19+ messages in thread From: Michael Feldman @ 1991-02-17 0:19 UTC (permalink / raw) In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes: >There is an unsafe aspect of passing access types as IN parameters in Ada >that is, sad to say, handled rather better in C++. > >In Ada, you can pass an access type to a function as an IN: > type Some_Foo... > type Pointer is access Some_Foo; > function Some_Bar (Some_Param : in Pointer)... >And then, inside the function, dereference the pointer and modify the >pointed-to construct. > >In C++, you can declare not only the pointer constant but the pointed >to construct constant as well. This allows passing by reference in a >read-only manner, which is NOT possible in Ada at present. Well now I'm curious. Given that only scalars and small structures are usually passed by copy, why would you want to guarantee reference passing for read-only parameters in such a kludgy way? Ada provides you with everything you need: - parameters large enough to cause performance concerns are passed by reference anyway (in any reasonable implementation, anyway); - IN parameters are read-only, no matter how they are passed. Am I missing some important other issue here? What aren't you getting from this combination of features? Mike Feldman 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? ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-17 0:19 ` Reference vs. copy semantics in passing parameters Michael Feldman @ 1991-02-17 18:54 ` Erland Sommarskog 1991-02-18 18:41 ` Doug Smith 1991-02-18 0:36 ` Jim Showalter ` (2 subsequent siblings) 3 siblings, 1 reply; 19+ messages in thread From: Erland Sommarskog @ 1991-02-17 18:54 UTC (permalink / raw) Also sprach Micheal Feldman (mfeldman@seas.gwu.edu): >Jim Showalter (jls@yoda.Rational.COM) writes: >>In C++, you can declare not only the pointer constant but the pointed >>to construct constant as well. This allows passing by reference in a >>read-only manner, which is NOT possible in Ada at present. > >Well now I'm curious. Given that only scalars and small structures are >usually passed by copy, why would you want to guarantee reference >passing for read-only parameters in such a kludgy way? Ada provides you >with everything you need: Don't get confused by terminology. Forget about passing mechanisms. Remember data abstraction. If you have a routine which takes a pointer parameter as IN, you are guaranteed that the *pointer* don't change, but the object pointed to may be completely altered. For instance look at: PROCEDURE P(X : IN ADT); Am I as a caller that Do_something from this signature guaranteed that P does not change X? Answer: No. If I look in the package specification I find that ADT is limited private. Only if I cheat and sneak into the private part and find that ADT is declared as a pointer-less type I know that X won't change. If there is a pointer, and often that's all an ADT is, P may change X just as much as it wants. Remember that as a user, I may perceive X as a completely static object. The practical implication is on the side of the ADT implementor. He may choose to define ADT as a pointer in order to be able to defer the record definition to the package body, and thereby reducing recompilation impact in case he adds or removes a field. The cost of this is that he loses compiler control of inadvertent changes to IN parameters, and we're back on the Pascal level. >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? Ada should not bind the implementors in order to make ugly programming unambiguous. Rather I think Ada is going too far when requiring a certain implementation in some situations. The IN, OUT and IN OUT modes are a beautiful invention with exception of the problems mentioned above. -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se "...I cannot understand someone saying 'Rush makes pretty good music, but they ARE commercial'." -- William J Bouma ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-17 18:54 ` Erland Sommarskog @ 1991-02-18 18:41 ` Doug Smith 0 siblings, 0 replies; 19+ messages in thread From: Doug Smith @ 1991-02-18 18:41 UTC (permalink / raw) In article <2635@enea.se> sommar@enea.se (Erland Sommarskog) writes: > Also sprach Micheal Feldman (mfeldman@seas.gwu.edu): > >Jim Showalter (jls@yoda.Rational.COM) writes: > >>In C++, you can declare not only the pointer constant but the pointed > >>to construct constant as well. This allows passing by reference in a > >>read-only manner, which is NOT possible in Ada at present. > > > >Well now I'm curious. Given that only scalars and small structures are > >usually passed by copy, why would you want to guarantee reference > >passing for read-only parameters in such a kludgy way? Ada provides you > >with everything you need: > > Don't get confused by terminology. Forget about passing mechanisms. > Remember data abstraction. > More specifically, notice how an ADT can be specified to control the ambiguity of parameter modes for pointers to complex data structures. Although a particular implementation of linked list might always initialize a header record, then never need to change it during Prepends, Appends, etc., IN OUT can enforce the intent of the operations. For example: package Linked_Integer_Operations is type Lists is limited private; procedure Append (List : in out Lists; Element : in Integer); private ... Declare Lists as an initialized record whose value doesn't have to change during the Append operation. end; Now the application engineer cannot accidently change a list that he did not originally intend to change: procedure Reorder_List (New_List : in out Lists; Old_List : in Lists) is begin Append (Old_List, 0); -- will not compile !!! end; -- RM 6.4.1(3): actual must be a variable name or a conversion -- RM 6.2(3): assignment to an IN parameter not allowed No matter how arrogant I become about my own programming skills, this kind of compile time checking has saved me many headaches! ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-17 0:19 ` Reference vs. copy semantics in passing parameters Michael Feldman 1991-02-17 18:54 ` Erland Sommarskog @ 1991-02-18 0:36 ` Jim Showalter 1991-02-18 1:42 ` Michael Feldman 1991-02-18 18:49 ` Arthur Evans 1991-02-18 13:10 ` madmats 1991-05-16 13:51 ` Alex Blakemore 3 siblings, 2 replies; 19+ messages in thread From: Jim Showalter @ 1991-02-18 0:36 UTC (permalink / raw) Yes, but you miss my point (I think?). It is not modification of the POINTER we are trying to prevent. We are trying to prevent modification of what the pointer points to, and there is currently no way to insure this in Ada. A doofus can break the rules with impunity. Why would it BE a pointer? Beats me, but these things do happen from time to time, and when they do it would be nice if the language made them safe. One gross thing that people do currently is give IN/OUT semantics to parameters on functions by passing a pointer and dereferencing it inside the function to modify what the pointer points to. There is no way to prevent this egregious behavior at present (note: many many people have also requested that 9x include IN/OUT's on functions, which would make the case for performing the trick just described even weaker). -- ***** DISCLAIMER: The opinions expressed herein are my own. Duh. Like you'd ever be able to find a company (or, for that matter, very many people) with opinions like mine. -- "When I want your opinion, I'll beat it out of you." ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-18 0:36 ` Jim Showalter @ 1991-02-18 1:42 ` Michael Feldman 1991-02-18 18:49 ` Arthur Evans 1 sibling, 0 replies; 19+ messages in thread From: Michael Feldman @ 1991-02-18 1:42 UTC (permalink / raw) In article <jls.666837388@yoda> jls@yoda.Rational.COM (Jim Showalter) writes: >Yes, but you miss my point (I think?). It is not modification of the >POINTER we are trying to prevent. We are trying to prevent modification >of what the pointer points to, and there is currently no way to insure >this in Ada. A doofus can break the rules with impunity. Hmmm.Are you implying that C++, or whatever, can guarantee that an entire linked list could be kept safe from modification by making its head pointer an IN parameter? Neat idea, but how on earth could it be implemented? If you mean only the directly designated value, i.e. the node (say) that the pointer points to but not the other nodes "down the line", I don't really think you've accomplished very much. > >Why would it BE a pointer? Beats me, but these things do happen from time >to time, and when they do it would be nice if the language made them safe. Well, this is a matter of taste. It's impossible (or nearly, IMHO) to make the language safe from people who insist on using side effects. The goal, it seems to me, is to make it difficult to _accidentally_ do stupid things. If people want to do them deliberately, they will find a way no matter how safe we think we are building things. > >One gross thing that people do currently is give IN/OUT semantics to >parameters on functions by passing a pointer and dereferencing it inside >the function to modify what the pointer points to. There is no way to >prevent this egregious behavior at present (note: many many people have >also requested that 9x include IN/OUT's on functions, which would make >the case for performing the trick just described even weaker). A dumb idea, if you ask me. People are trying to make Ada behave like C. If they try hard enough to subvert the safety that Ada provides, they will find a way to succeed. Ada9x is looking at this issue (it's in the requirements document, but I don't recall if it's a requirement or a study topic); I hope they leave this as it is in Ada83. As I recall, the argument for allowing IN/OUT's on functions is that since nonlocal references are allowed on functions, allowing IN/OUT's is a clearer way of doing the same thing. There is a certain logic to this, I must say. But if you encapsulate the function in a package, using the nonlocal reference only to maintain state data, with the client unable to muck with the state variable, then an IN/OUT parameter does _not_ accomplish the same thing, because it exposes the state variable to the client. Mike Feldman ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-18 0:36 ` Jim Showalter 1991-02-18 1:42 ` Michael Feldman @ 1991-02-18 18:49 ` Arthur Evans 1991-02-19 2:05 ` Michael Feldman 1 sibling, 1 reply; 19+ messages in thread From: Arthur Evans @ 1991-02-18 18:49 UTC (permalink / raw) Cc: jls Jim Showalter (jls@yoda.Rational.COM) comments that Ada 9X might permit functions to have parameters of mode IN OUT or OUT. An early draft of the Requirements Document included a requirement for such a change. However, because of many comments opposing the change it was removed from the final document. Art Evans ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-18 18:49 ` Arthur Evans @ 1991-02-19 2:05 ` Michael Feldman 0 siblings, 0 replies; 19+ messages in thread From: Michael Feldman @ 1991-02-19 2:05 UTC (permalink / raw) In article <16152@as0c.sei.cmu.edu> ae@sei.cmu.edu (Arthur Evans) writes: >Jim Showalter (jls@yoda.Rational.COM) comments that Ada 9X might permit >functions to have parameters of mode IN OUT or OUT. > >An early draft of the Requirements Document included a requirement for >such a change. However, because of many comments opposing the change it >was removed from the final document. A good decision, IMHO. A function should be as nearly a "black box" as possible, which has no side effects. In Ada a function that has state memory (a pseudo-random number generator, for example), must have a side effect (of modifying a variable of the package body it's in, presumably). This could have been prevented if Ada had allowed _static_ data structures in subprograms, a la PL/1, C, and Fortran. But alas, it doesn't, and I'm sure it won't. But in any case, the client of the function should not be able to cause side effects. Just because other languages have "value-returning procedures" or "functions with side effects" (dpending on how you want to look at it) doesn't mean Ada needs to. Let functions be functions. Mike Feldman ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-17 0:19 ` Reference vs. copy semantics in passing parameters Michael Feldman 1991-02-17 18:54 ` Erland Sommarskog 1991-02-18 0:36 ` Jim Showalter @ 1991-02-18 13:10 ` madmats 1991-02-19 19:00 ` Robert I. Eachus 1991-05-16 13:51 ` Alex Blakemore 3 siblings, 1 reply; 19+ messages in thread From: madmats @ 1991-02-18 13:10 UTC (permalink / raw) 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? I think the objections would be that there should be nothing in Ada that prevents its implementation on a distributed system (without shared memory). Remote procedure calls and entries cannot reasonably be done if the reference mechanism is used for parameter passing, even for large structures. Mats ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-18 13:10 ` madmats @ 1991-02-19 19:00 ` Robert I. Eachus 0 siblings, 0 replies; 19+ messages in thread From: Robert I. Eachus @ 1991-02-19 19:00 UTC (permalink / raw) 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-02-17 0:19 ` Reference vs. copy semantics in passing parameters Michael Feldman ` (2 preceding siblings ...) 1991-02-18 13:10 ` madmats @ 1991-05-16 13:51 ` Alex Blakemore 1991-05-17 8:19 ` Matthias Ulrich Neeracher ` (2 more replies) 3 siblings, 3 replies; 19+ messages in thread From: Alex Blakemore @ 1991-05-16 13:51 UTC (permalink / raw) In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes: > In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes: > In C++, you can declare not only the pointer constant but the pointed > to construct constant as well. This allows passing by reference in a > read-only manner, which is NOT possible in Ada at present. This sounds like a nice safety feature but can callers really rely on it ? Even if the C++ language prevents updating the object if the pointer is declared appropriately, does it prevent assignment to a normal pointer which will allow the referenced object to be updated ? I know very little about C++, but will attempt to pose an argument against this feature in Ada terms. Perhaps someone with C++ knowledge could explain why this feature is really desirable ? Consider this Ada flavored example, where constant means the referenced object may not be updated. procedure look_at_object (p : in CONSTANT ptr_to_object); procedure look_at_object (p : in CONSTANT ptr_to_object) is temp : ptr_to_object; begin temp := p; -- is this legal in C++ ? p.all := anything; end; Unless C++ prevents the assignment to another pointer above, then the feature can be easily subverted (purposely or accidently). that means callers have to a. trust that the body really obeys the implication in the parameter mode to not update the referenced object or b. examine the body to make sure. Since the new mode cannot be really trusted (as defined above), it doesnt really aid in reasoning about a program's behavior. It can prevent some simple errors that are relatively easy to spot (e.g. p.anything on lhs of assignemnt) but can't prevent the more tricky types of errors. It can even do harm by giving a false sense of assurance. Of course this argument falls apart if you invent more rules to prevent making copies of such pointers in anyway, but can you do that without making the language even more complex? Besides the assignment you'ld have to make sure parameters of such modes could only be passed by the same mode to other subprograms. -- --------------------------------------------------------------------- Alex Blakemore blakemore@software.org (703) 742-7125 Software Productivity Consortium 2214 Rock Hill Rd, Herndon VA 22070 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-05-16 13:51 ` Alex Blakemore @ 1991-05-17 8:19 ` Matthias Ulrich Neeracher 1991-05-17 13:44 ` Markku Sakkinen 1991-05-28 5:28 ` Kenneth Almquist 2 siblings, 0 replies; 19+ messages in thread From: Matthias Ulrich Neeracher @ 1991-05-17 8:19 UTC (permalink / raw) In article <1991May16.135103.1688@software.org> blakemor@software.org (Alex Blakemore) writes: >In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes: >> In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes: >> In C++, you can declare not only the pointer constant but the pointed >> to construct constant as well. This allows passing by reference in a >> read-only manner, which is NOT possible in Ada at present. > >This sounds like a nice safety feature but can callers really rely on it ? >Even if the C++ language prevents updating the object if the pointer is >declared appropriately, does it prevent assignment to a normal pointer >which will allow the referenced object to be updated ? >[...] >Consider this Ada flavored example, where constant means the referenced >object may not be updated. > >procedure look_at_object (p : in CONSTANT ptr_to_object); > >procedure look_at_object (p : in CONSTANT ptr_to_object) is > temp : ptr_to_object; >begin > temp := p; -- is this legal in C++ ? > p.all := anything; >end; > >Unless C++ prevents the assignment to another pointer above, then the feature >can be easily subverted (purposely or accidently). [Sorry to post C++ to comp.lang.ada, but the question is posted here] In C++, the above assignment is illegal, so the risk of subverting the feature accidentally is low. On the other hand, the assignment can easily be done if an explicit type cast to the non-constant type is employed in the right-hand side, so the feature can indeed easily be subverted purposely. I tend to agree with this design philosophy, as I believe that it is beneficial to try to guard programmers from their own stupid... I mean fallibility, but that there is little use of trying to control their malice with programming language features. A borderline case is, of course, programmer's lazyness. Matthias ----- Matthias Neeracher neeri@iis.ethz.ch "These days, though, you have to be pretty technical before you can even aspire to crudeness." -- William Gibson, _Johnny Mnemonic_ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-05-16 13:51 ` Alex Blakemore 1991-05-17 8:19 ` Matthias Ulrich Neeracher @ 1991-05-17 13:44 ` Markku Sakkinen 1991-05-28 5:28 ` Kenneth Almquist 2 siblings, 0 replies; 19+ messages in thread From: Markku Sakkinen @ 1991-05-17 13:44 UTC (permalink / raw) In article <1991May16.135103.1688@software.org> blakemor@software.org (Alex Blakemore) writes: >In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes: >> In article <jls.666659373@yoda> jls@yoda.Rational.COM (Jim Showalter) writes: >> In C++, you can declare not only the pointer constant but the pointed >> to construct constant as well. This allows passing by reference in a >> read-only manner, which is NOT possible in Ada at present. I think the original poster has erred here: nothing prevents an Ada implementation from passing 'in' parameters by reference whenever that is most convenient or efficient. (I think Ada's 'in' parameters are a significant improvement over the value parameters of Algol and Pascal.) However, the 'pointer to constant' feature of C++ may be worth discussing in this newsgroup, because its applicability is _not_ restricted to parameter passing. The meaning of 'const' in C++ should be noted. If Ada had the same approach to constants, we could have something like: type object; type immutable is constant object; type ptr_to_object is access object; type ptr_to_immutable is access immutable; An 'immutable' value could be directly assigned to an 'object' variable, and a 'ptr_to_object' value to a 'ptr_to_immutable' variable. Thus, types like 'ptr_to_immutable' are, strictly speaking, not "pointer to constant" types, but rather "non-modifying pointer" types: the object pointed to may well be modified, but not via this reference. >This sounds like a nice safety feature but can callers really rely on it ? >Even if the C++ language prevents updating the object if the pointer is >declared appropriately, does it prevent assignment to a normal pointer >which will allow the referenced object to be updated ? Of course, you cannot _really_ rely on anything in a C-based language: by fooling around with pointers you can even overwrite _code_ unless the operating systems protects code segments. Such things are "illegal" in principle, although it is difficult to imagine a C or C++ implementation that could catch them. -- But indeed, the kind of assignment (or cast) that you asked about is fully _legal_ C++ according to the most authoritative definition! >I know very little about C++, but will attempt to pose an argument >against this feature in Ada terms. Perhaps someone with C++ knowledge >could explain why this feature is really desirable ? > >Consider this Ada flavored example, where constant means the referenced >object may not be updated. > ... >procedure look_at_object (p : in CONSTANT ptr_to_object) is > temp : ptr_to_object; >begin > temp := p; -- is this legal in C++ ? ^^^^^^^^^ > p.all := anything; >end; An assignment corresponding to the above is _not_ legal in C++, the legal case would correspond ("Adaified") to: temp := ptr_to_object (p); Using my previous type declarations, the procedure header would be: procedure look_at_object (p : in ptr_to_immutable) Actually, this whole example is not very convincing of the need for such pointer types. If we take the above C++-like meaning of "non-modifying pointer", the procedure could just as well be declared as procedure look_at_object (o : in object) If we would like a true "pointer to constant" meaning, then: procedure look_at_object (i : in immutable) >Unless C++ prevents the assignment to another pointer above, then the feature >can be easily subverted (purposely or accidently). [...] Yes, but I think that the feature combined with some programming discipline is nevertheless useful. Of course, if this feature were to be introduced in Ada (or some other language with stronger typing than C++), one would probably not allow such dangerous conversions. (They fit the general spirit of C and C++, but not the spirit of Ada.) > ... > Of course this argument falls apart if you invent more rules to prevent >making copies of such pointers in anyway, but can you do that without >making the language even more complex? Besides the assignment you'ld have to >make sure parameters of such modes could only be passed by the same mode >to other subprograms. Since "pointer to constant something" is regarded as a distinct type and not as a specific device for parameter passing, I don't think it would cause any "cascading" complexity; existing type rules would be quite sufficient. Markku Sakkinen Department of Computer Science and Information Systems University of Jyvaskyla (a's with umlauts) PL 35 SF-40351 Jyvaskyla (umlauts again) Finland SAKKINEN@FINJYU.bitnet (alternative network address) ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Reference vs. copy semantics in passing parameters 1991-05-16 13:51 ` Alex Blakemore 1991-05-17 8:19 ` Matthias Ulrich Neeracher 1991-05-17 13:44 ` Markku Sakkinen @ 1991-05-28 5:28 ` Kenneth Almquist 2 siblings, 0 replies; 19+ messages in thread From: Kenneth Almquist @ 1991-05-28 5:28 UTC (permalink / raw) >In article <2742@sparko.gwu.edu> mfeldman@seas.gwu.edu () writes: >> In C++, you can declare not only the pointer constant but the pointed >> to construct constant as well. This allows passing by reference in a >> read-only manner, which is NOT possible in Ada at present. This feature has also been included in the ANSI C standard. blakemor@software.org (Alex Blakemore) asks: > This sounds like a nice safety feature but can callers really rely on it ? > Even if the C++ language prevents updating the object if the pointer is > declared appropriately, does it prevent assignment to a normal pointer > which will allow the referenced object to be updated ? The "constant" attribute is part of the type, so the type checking system makes this secure *unless* the type system is circumvented by the use of a type cast. (By "type cast", I mean the C equivalent of Ada's UNCHECKED_CONVERSION.) The rule is that a pointer to a non-constant object can be assigned to a pointer to a constant object, but not the other way around. (Assignment includes parameter passing.) A problem with the "constant" attribute is that it is not inherited properly. Consider a routine that looks up an entry in a data structure like a tree or a string, and returns a pointer to the element found. The returned pointer should point to a constant object iff the data structure was declared to be constant, but the C type system doesn't handle this. For this reason, several routines in the standard ANSI C library are defined in such a way that they cannot be implemented without using type casts. Kenneth Almquist ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: ADA Compiling Query 1991-02-11 15:06 ADA Compiling Query Gordon Russell 1991-02-12 19:01 ` Michael Feldman 1991-02-13 21:16 ` Jeff Bartlett @ 1991-02-18 14:33 ` stt 2 siblings, 0 replies; 19+ messages in thread From: stt @ 1991-02-18 14:33 UTC (permalink / raw) Re: passing structured parameters by reference 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? Here are some important reasons for allowing by-copy parameter passing: 1) It supports parameter passing between parts of a distributed program which don't share memory. 2) It allows a slice of a packed array to be copied into an aligned temporary, rather than forcing every subprogram to handle a descriptor for an unaligned parameter. 3) It allows very short arrays/records to be passed in registers (e.g. a packed array of 16 booleans). 4) It is necessary when the actual parameter is in the form of a type conversion, and the target and source type don't have the same representation (e.g. one is packed and the other isn't). S. Tucker Taft Intermetrics, Inc. Cambridge, MA 02138 ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~1991-05-28 5:28 UTC | newest] Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1991-02-11 15:06 ADA Compiling Query Gordon Russell 1991-02-12 19:01 ` Michael Feldman 1991-02-13 21:16 ` Jeff Bartlett 1991-02-14 16:45 ` Michael Feldman 1991-02-15 23:09 ` Jim Showalter 1991-02-17 0:19 ` Reference vs. copy semantics in passing parameters Michael Feldman 1991-02-17 18:54 ` Erland Sommarskog 1991-02-18 18:41 ` Doug Smith 1991-02-18 0:36 ` Jim Showalter 1991-02-18 1:42 ` Michael Feldman 1991-02-18 18:49 ` Arthur Evans 1991-02-19 2:05 ` Michael Feldman 1991-02-18 13:10 ` madmats 1991-02-19 19:00 ` Robert I. Eachus 1991-05-16 13:51 ` Alex Blakemore 1991-05-17 8:19 ` Matthias Ulrich Neeracher 1991-05-17 13:44 ` Markku Sakkinen 1991-05-28 5:28 ` Kenneth Almquist 1991-02-18 14:33 ` ADA Compiling Query stt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox