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,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,a00006d3c4735d70 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2004-03-02 14:06:18 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!crtntx1-snh1.gtei.net!news.gtei.net!newsfeed1.easynews.com!newsfeed3.easynews.com!easynews.com!easynews!border1.nntp.sjc.giganews.com!nntp.giganews.com!local1.nntp.sjc.giganews.com!nntp.comcast.com!news.comcast.com.POSTED!not-for-mail NNTP-Posting-Date: Tue, 02 Mar 2004 16:06:17 -0600 Date: Tue, 02 Mar 2004 17:06:16 -0500 From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: In-Out Parameters for functions References: <4020C947.81A6D703@0.0> <40236C0B.E988E003@0.0> <1077634311.254581@master.nyc.kbcfp.com> <1077718871.47635@master.nyc.kbcfp.com> <54cp3095jmv8s17h63d4bjdus0tec7l7pt@jellix.jlfencey.com> <1077721343.481619@master.nyc.kbcfp.com> <1077727853.904323@master.nyc.kbcfp.com> <1077810250.28474@master.nyc.kbcfp.com> <1078162736.111267@master.nyc.kbcfp.com> <8qW0c.24142$TF2.22229@nwrdny02.gnilink.net> <1078241064.575279@master.nyc.kbcfp.com> <1078245216.689285@master.nyc.kbcfp.com> In-Reply-To: <1078245216.689285@master.nyc.kbcfp.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: NNTP-Posting-Host: 24.147.77.160 X-Trace: sv3-K1EQw6CgE/u8RaiGafQ5n4AdOL0PL8UDZ5gJTc8Qq6tpLDk3qJwMMxw9o+wLthMDwbRuRn3FKrh0fWB!hYXjxAXNtg4wuhLBZqVhaRkCeD7DrBJQwS10dVmHFpSXx7kJvYrknSfpe4XORQ== X-Complaints-To: abuse@comcast.net X-DMCA-Complaints-To: dmca@comcast.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.1 Xref: archiver1.google.com comp.lang.ada:6015 Date: 2004-03-02T17:06:16-05:00 List-Id: Hyman Rosen wrote: > That's not really the point. If I know in micro-detail where a check > is failing, I could just as easily make it not fail. What I expected > (which will probably earn me another blast from RE for not getting > the Ada mindset) was that the reason for l-d checks is to prevent the > kind of errors you find in C, namely undetected erroneous changes that > trigger problems at some remove from the place where they occurred. > It seems to me that the Ada rules allow the same sort of thing to > happen - if I have a handler at a high level for a language-defined > error, it's possible that any number of objects may have been left in > an abnormal state when the exception triggered, and I will encounter > erroneous (and possibly undetected) behavior at some later point. First of all, on this point I agree with you that the Ada 95 rules go too far. Fortunately, if you look at the example I posted, most Ada compilers are very careful about taking advantage of the 11.6(6) freedoms when exceptions can happen. The real problem is that it is very hard to write a rule that makes sense given the way today's CPUs are built. The CPU will reorder instructions at run-time, and only some CPUs will pretend, if an instruction causes an interrupt, that the ordering was precise. I could probably reference half a dozen architecture manuals for you, that detail exactly how precise and non-precise interrupts are serviced. But it is lots of really boring trivia to sort through to figure out what happens in a case that you might care about. But I do read those manuals, thoroughly at least for most SPARC family processors, x86 processors and now AMD64/IA-32e CPUs. You have to remember is that the implementations vary, even within a processor family, and worse some processors have multiple modes, with different interrupt behavior. So the current (Ada 95) RM rules really amount to do what makes sense on the real hardware--because the compiler compiles to an ISA, and for many ISAs, the rules change from implementation to implementation. Fortunately, as the program I just posted shows, most compilers still obey the old Ada 83 meta-rule: "Thou shalt not reason from erroneousness." The program as written is (intentionally) erroneous. Not causes a bounded error, which is a much more tightly limited case, but erroneous. Would I write code like that 'for real'? Of course not. But it doesn't prevent me from grumbling about how difficult it can be for a programmer to avoid erroneousness in some contexts. (Technically what you have to do is write subprograms that handle exceptions internally as follows: procedure Foo(...) is -- object declarations here should never raise an exception. -- put things that can in a nested block. begin declare -- potentially problematical variables begin -- do any additional checking here, but don't assign to any -- out or in out parameters. -- firewall This is usually a call to some external procedure or -- function that is not inlined. This can be, and often is in -- code that I write, a call that is needed anyway. -- do any assignments to globals or parameters here. exception when Constraint_Error => -- fix the problem either by using a different -- algorithm, or by a nested call to Foo with modified parameters. when others => raise; -- or whatever, it is usually Constraint_Error that takes all the -- work, and any other exceptions are passed back to the caller. end; -- nested block. end Foo; All that looks like a lot of work, but it isn't usually. It is just that most programmers Ada or otherwise have no idea of what it takes to write a subprogram that actually deals with Constraint_Error instead of just renaming it or letting it propagate to the caller. To give just one example, think about an Inverse function for matrices. There are matrices for which the inverse is well defined, there are cases where the matix is singular, and there is a third group of cases where the matrix is ill conditioned or stiff. Often it takes a lot more CPU cycles to run the cases which can deal with ill-conditioned or stiff matrices, so you really do want to try say, simple LU decomposition first. If you do go to that effort, putting the firewall call in is no big deal. Writing the code so that you can begin over when needed is often more work, but in this case you are not inverting the matrix in place (unless you pass the matrix with an access parameter). Now if anyone wants to submit a suggestion to Ada-Comment suggesting that there actually be a language defined procedure Firewall that does nothing but what its name implies, fine. Personally I find it easy enough to have my own version around and call it. -- Robert I. Eachus "The only thing necessary for the triumph of evil is for good men to do nothing." --Edmund Burke