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,319ef0454c7765d5 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1995-03-24 20:56:29 PST Newsgroups: comp.lang.ada Path: nntp.gmd.de!news.rwth-aachen.de!news.rhrz.uni-bonn.de!news.uni-stuttgart.de!rz.uni-karlsruhe.de!xlink.net!howland.reston.ans.net!math.ohio-state.edu!uwm.edu!fnnews.fnal.gov!gw2.att.com!nntpa!not-for-mail From: ka@socrates.hr.att.com (Kenneth Almquist) Subject: Re: Why no exception hierarchy ? Message-ID: Sender: news@nntpa.cb.att.com (Netnews Administration) Nntp-Posting-Host: socrates.hr.att.com Organization: AT&T References: <3ksv4s$f9e@news.uni-c.dk> Date: Sat, 25 Mar 1995 01:50:38 GMT Date: 1995-03-25T01:50:38+00:00 List-Id: An example of something that the Ada 83 exception mechanism did not handle well is binding UNIX system calls to Ada. POSIX.5 maps all system call errors into a single exception named POSIX_Error, and provides a per-task error code variable. This is dangerous. Consider the following C code: if (unlink("file") < 0) printf("Could not delete file: %s\n", strerror(errno)); A naive translation of this code to Ada is: begin unlink("file"); exception when posix_error => put("Could not delete file: "); put(image(get_error_code)); new_line; end; This translation is incorrect because "image(get_error_code)", which corresponds to the C code "strerror(errno)" is evaluated after the first call to "put". If "put" modifies errno, the wrong error code will be printed. In short, passing data around in global variables is dangerous and leads to unreadable code. (Try showing the above code without the surrounding text to your office mate and see how long it takes him/her to spot the bug.) As far as I can tell, Ada 95 provides two ways to resolve this problem, neither of which I entirely like. One is to encode the error code in the exception message. Then we could have: function get_error_code(x: exception_occurence) return error_code; which would translate the exception_message into an error code. This seems to be an abuse of the intended purpose of the exception_message, which is to provide human-readable information on the exception. In addition, passing the error code around as a string seems cumbersome and inefficient. On the plus side, it is backward compatible with the existing POSIX.5 binding. The other approach is to map each error code to a separate exception and use query functions on exception identities to implement classes. In this case, one would write: exception when occurence : others => if is_system_call_error(exception_identity(occurence)) then -- code to handle exception goes here else raise; -- we aren't interested in this exception. end if; end; This approach leads to more complicated code than is ideal, because we write two tests for the identity of the exception (the "when" clause and the "if" statement). In Ada 83 it is possible to determine which exceptions are handled by a routine by simply scanning the "when" clauses; here you have to read the "if" statement as well. Have I missed overlooked any possibilities? Was this problem (making UNIX bindings to Ada) discussed during the Ada 9X revision process? Kenneth Almquist