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-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6a0391eb7e0327d5 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-02-08 18:04:08 PST Newsgroups: comp.lang.ada Path: archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!64.152.100.70.MISMATCH!sjc70.webusenet.com!news.webusenet.com!nf3.bellglobal.com!snoopy.risq.qc.ca!elk.ncren.net!news.umass.edu!world!news From: Robert A Duff Subject: Re: Ada style of passing 'in' parameters considered dangerous? User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 Sender: news@world.std.com (Mr Usenet Himself) Message-ID: Date: Sun, 9 Feb 2003 02:01:42 GMT Content-Type: text/plain; charset=us-ascii References: <86isvuzabx.fsf@hoastest1-8c.hoasnet.inet.fi> NNTP-Posting-Host: shell01.theworld.com Mime-Version: 1.0 Organization: The World Public Access UNIX, Brookline, MA Xref: archiver1.google.com comp.lang.ada:33921 Date: 2003-02-09T02:01:42+00:00 List-Id: Antti Sykari writes: > Hello, > > I recently asked in comp.compilers advice about implementing a > parameter passing policy for a rather close-to-machine language. Yes, I saw that thread. The problem with this Ada rule is that it violates abstraction. You don't know whose responsibility it is to worry about aliases -- the caller or callee. >...My > suggestion for the method of passing 'in' parameters to procedures > was: Pass everything as readonly by default, and leave the > by-reference/by-copy decision to the compiler. > > It was pointed out that Ada already has this kind of policy. In one > reply (<03-01-169@comp.compilers>), it was mentioned that it is a > time-bomb in Ada, since it permits the programmer to write code that > is erroneous but the compiler cannot detect this. Indeed, the > standard ([1]) says that if an object has been passed via an > unspecified parameter passing mechanism, is written via one access > path and read via another, "possible consequences are that > Program_Error is raised, or the newly assigned value is read, or some > old value of the object is read". > > For example, in the simplest case, a procedure can take a readonly > 'in' argument "arg1" of type X, and an "in out" argument of the same > type. Then, if it writes in arg2 and after that reads arg1, this might > cause a run-time error or other implementation-defined behavior -- but > only if the procedure is called with two identical arguments. > > Of course, the erroneous behavior might occur in a more subtle way, > which is not expected to happen. I just can't think of any realistic > example where this undefinedness would really hurt. How about this example: We have a record representing fractions of whole numbers: type Fraction is record Numerator: Integer; Denominator: Positive; end record; procedure Reciprocal(Result: out Fraction; X: Fraction); -- Sets Result to the reciprocal of X. procedure Reciprocal(Result: out Fraction; X: Fraction) is begin if X.Numerator > 0 then Result.Numerator := X.Denominator; Result.Denominator := X.Numerator; ... etc It seems reasonable (without seeing the body of Reciprocal) to do: Reciprocal(Foo, Foo); If Fractions are passed by copy (which is probably most efficient, since they fit in just two registers), then it works fine. If they're passed by reference, we get the wrong answer. Of course Reciprocal could be written to avoid the problem (e.g. write it as a function instead). That would be less efficient in the non-alaised case. But the Ada RM does not make it clear whose responsibility this problem is -- the caller or the callee. In Fortran, the *call* would be wrong. > My concerns here are: > > - Is this generally considered a dangerous thing in Ada (or in > general)? I consider it a problem in Ada. But many other languages are worse in this regard. > - Have you encountered a non-trivial real-life case where the > programmer has shot himself in the foot in the form of > implementation-defined behavior because of the error mentioned above? > I'd be interested to hear of any such cases. I don't know. I would feel more comfortable if one could *prove* that such things can't happen. > - If there are such cases, could it have been prevented by having > different policy in the language? Yes. >...Do you think it would've been > better to force the programmer to specify the parameter passing > mechanism, for example? There are drawbacks to that, too: - One normally wants the most efficient mechanism, which depends on the sizes of the parameters wrt register size. But that's machine dependent, so the compiler ought to deal with it. - You can't (efficiently) pass components of packed records by reference. The Pascal rule in this regard is ugly. (Similar issue: slices of arrays.) One possible solution is to disallow cases that might be aliased. But that would require more information than is available to an Ada compiler -- it would need to know about global variables referenced by each procedure, for example. - Bob