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=0.7 required=5.0 tests=BAYES_00,MSGID_RANDY autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,dabd2d2ffbcf1daa X-Google-Attributes: gid103376,public From: Robert Dewar Subject: Re: Exiting from a function or procedure Date: 2000/04/22 Message-ID: <8ds3qe$q2d$1@nnrp1.deja.com> X-Deja-AN: 614224018 References: X-Http-Proxy: 1.0 x33.deja.com:80 (Squid/1.1.22) for client 205.232.38.14 Organization: Deja.com - Before you buy. X-Article-Creation-Date: Sat Apr 22 11:52:49 2000 GMT X-MyDeja-Info: XMYDJUIDrobert_dewar Newsgroups: comp.lang.ada X-Http-User-Agent: Mozilla/4.61 [en] (OS/2; I) Date: 2000-04-22T00:00:00+00:00 List-Id: Well first of all let's start with your last statement: > It does give me a warning, but some thing do happen to > some C/C++ compilers so i didn't bothered in that message Big mistake! Never ignore warnings from GNAT. They almost always point to something that is wrong, and if you don't understand them, you should get someone to help you. Here is a cleaned up version of your function: function "+" (Izq, Der: in Term) return Term is Aux : Term; Error_Suma : exception; begin if (Izq.Exponente = Der.Exponente) then Aux.Coeficiente := Izq.Coeficiente + Der.Coeficiente; Aux.Exponente := Izq.Exponente; return Aux; else raise Error_Suma; end if; exception when error_suma => Put(" ERROR !!!"); end "+"; Now when you compile that, you get: 20. Put(" ERROR !!!"); | >>> warning: "return" statement missing following this statement >>> warning: Program_Error may be raised at run time and indeed this warning is 100% accurate, and points to the serious bug in your function. if the line ERROR is printed, then indeed Program_Error will be raised, and it is pretty likely (I would guess 100% if you are a beginner) that this was NOT intentional. So NEVER EVER ignore warnings, consider them as errors. In fact you might want to use -gnatwe so the compiler will treat them as errors enforcing this discipline. The particular problem is that a function MUST terminate with a return statement for ALL possible excecution paths, and clearly your function disobeys this rule for the case where an exception is raised. We will address the fix below. But before we do, several style comments on your program, illustrated by the clean up above. a) indent properly, using standard style, you indented a bit but in an inconsistent manner and indentation is one thing that is pretty uniform in Ada, because the RM indicates a strong recommendation for indentation. b) use upper/lower case for identifiers as I have done above, this is not required, but again is very much the most common Ada standard. There are other acceptable capitalization styles used sometimes in Ada, but all lower case is NOT one of them. So get rid of that unwelcome C habit! c) Use a bit more white space to let the code breathe. This is personal taste, but again is pretty standard Ada style. d) Repeat the name of the function on the end line e) don't put unnecessary parentheses around expressions. In particular avoid doing this for conditionals, that's another C habit that need not be imported into Ada. Those comments are style comments reflected in the cleaned up code above. Now for some more extensive programming comments. a) use comments. Students often get into the appalling habit of writing code first and commenting it later. That is terrible for three reasons: 1. You don't get into the life long habit of always writing comments and if you don't get into that habit your code will NEVER be well documented. 2. Going back and adding documentation later works for trivial programs but does not scale up, you simply cannot do this on large programs 3. If you have no comments in the code as you write it, it makes it much harder for people to help (if you were one of my students I would refuse to help at all, because I would have told you in advance that you had better not ever show me uncommented code, since I won't help, but I will note it down and take off points for the assignment, and my TA's are instructed the same way :-) b) use decent names for things, not abbreviations. I cannot even guess what Izq means. One might guess that Der is deriviative, but if so, then spell it out. It's a bit more work to write, but in Ada, the cardinal rule is to write code that can be easily read. A decent editor that does name completion can help if you are a slow typist :-) c) Perhaps this is jumping a bit far from what you know, but likely the better code for the two assignments is Aux := (Coefiente => Izq.Coeficiente + Der.Coeficiente, Exponente => Izq.Exponente); You can probably guess how this works just by looking at the example. Technically it is a record aggregate, and you should be able to find the detailed description in your Ada book. It has the advantage of insisting that you remember to set all fields. That does not really matter when there are only two of them, but it can be a real advantage if there are many. You can go a step further, just eliminate Aux completely from your program, and write: return (Coefiente => Izq.Coeficiente + Der.Coeficiente, Exponente => Izq.Exponente); OK, now finally back to the original issue. You have an error situation in this function, and the proper thing to do is to raise an exception, but it is wrong to define this exception INSIDE the function, why? because the idea of an exception is to let the CALLER decide what to do, and for that the caller must be able to see the exception. How to deal with this, well the function "+" must appear inside a package, and that means the specification appears in the package spec. Here is an idea of how that should be done: function "+" (Izq, Der: in Term) return Term; -- This function takes two .... and ..... and returns a -- Term which .... The exponents of Izq and Der must be -- equal -- -- Error conditions: raises Error_Suma if the exponents -- are unequal. I can't fill in the .... since I don't know what this does :-). Just to remind you, the body now looks like: function "+" (Izq, Der: in Term) return Term is begin if Izq.Exponente = Der.Exponente then return (Coefiente => Izq.Coeficiente + Der.Coeficiente, Exponente => Izq.Exponente); else raise Error_Suma; end if; end "+"; Now, it is up to the caller to decide what to do about this error. For a simple program it may well be enough to do nothing at all. Now what happens if the error occurs, well you have an unhandled exception and so the program terminates with a nice message saying that the exception Error_Suma was unhandled, and then you can if necessary go into the debugger and find out why that happened. Note how much nicer that is than the C style of returning an error code which if you forget to check it, means that the error is blithely ignored. This has caused bugs in many many C programs. For example early versions of the Unix editor just ignored a disk full condition, so you lost your edited file with no warning that this had happened. Or perhaps the CALLER will have an exception handler to detect the error and take appropriate action. One further point. In some real large programs, there is a protocol of logging errors, and that may mean it is appropriate to modify your function as follows: function "+" (Izq, Der: in Term) return Term is begin if Izq.Exponente = Der.Exponente then return (Coefiente => Izq.Coeficiente + Der.Coeficiente, Exponente => Izq.Exponente); else raise Error_Suma; end if; exception when Error_Suma => Error_Log ("error occured in "+" with args ...."); raise; end "+"; Here the raise with no argument (often called a reraise), reraises the same exception, so that the caller can deal with it as appropriate. Finally a quick note about the advice you received to interface the C function exit. This was non-Ada advice, and shows the risk of getting advice from CLA, you can often get correct advice which answers the wrong problem. Interfacing exit answered the question of "how can I exactly duplicate the style and content of my C program in Ada?" But that's not what we are interested in doing here since you are learning Ada :-) Robert Dewar Sent via Deja.com http://www.deja.com/ Before you buy.