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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,8ed8f00df051b989 X-Google-Attributes: gid103376,public From: Laurent Guerby Subject: Re: Ada exception limitations Date: 2000/02/26 Message-ID: <86ln48yr3o.fsf@ppp-111-174.villette.club-internet.fr>#1/1 X-Deja-AN: 590261925 References: <89738j$f27$1@nnrp1.deja.com> X-Trace: front2.grolier.fr 951575058 13695 194.158.111.174 (26 Feb 2000 14:24:18 GMT) Organization: Club-Internet (France) NNTP-Posting-Date: 26 Feb 2000 14:24:18 GMT Newsgroups: comp.lang.ada Date: 2000-02-26T14:24:18+00:00 List-Id: jehamby@lightside.com writes: > [...] My question is: have any attempts been made to update the standard > to make Ada exception handling more like C++ or Java? Does GNAT > offer any extended capabilities in this area? As you found out, the Ada language designers ruled out the possibility of attaching data to an exception, they felt that a string was enough for most uses, and since an implementations is allowed to place a static restriction on the length of the string, it can be efficient (and trouble free from a semantic point of view, no risk of having the exception object constructor raising an exception, etc..). In one project I'm working on, we use exceptions when we find out some problem with the user input, and the last layer is expected to report a clear and informative message to the user, and this means that the length of the message is likely to exceed the built-in limit for excepion message length of our compiler (GNAT with support from ACT Europe). We handle the issue with a dedicated "Errors" package that provide three entry points: procedure Error (Message : in String); procedure Error (E : in Exception_Occurrence; Message : in String); procedure Purge_Error (E : in Exception_Occurrence; X : out Some_Stack_Of_String_Data_Structure); The idea is that when there is a problem, the code calls if Ooops then Error ("aie aie aie"); end if; which allocates an internal id, store the message in a table indexed by the id, and raise an exception with the id encoded in it. You can add context during the propagation by calling the second entry point: exception when E : others => Error (E, "problem while computing stuff"); If Error finds the id in E, then it appends the message, otherwise it creates a new id, store the compiler message as first entry (prefixed with "internal error"), and raises the exception with the encoded id. Purge_Error is used by the top layer to get the message to the user (it could be a disk log), and has the effect of freeing data associated with the exception. If you don't purge, you'll leak some memory. You'll have not to forget protecting the error data against concurrent access in a multitasking environment. If you're working in a distributed Annex E setup, you might have to encode node information in the message, otherwise, you can extend your communication protocol to transmit the exception information and continue propagation on the receiving side. Note that the main assumption here is that you use exception for *exceptional* and unpredictable cases. (There is only one place in our code where we recover from an exception, and it is for covering up known numerical instabilities.) The rule we follow is that if there are likely error outcomes, we use an explicit output or result parameter for it, not exceptions. Note that this helps debugging because when we're after a problem, the first exception raised points directly to the problem. Your mileage may vary. Hope this helps, --LG