TIP: Click on subject to list as thread! ANSI
echo: public_domain
to: Paul Edwards
from: Paul Markham
date: 1994-01-23 10:52:14
subject: pdgoal.txt 1/

PM>> You are missing my point. I'm not criticing the error handling routines.

 PM>> What I'm criticising is the documentation which claims it does things it

 PM>> can't. I agree with you on the need for this type of facility, but there

 PM>> is no way your does everything it claims to do.



 PE> I guess there's two separate things here.  One is the general

 PE> error-handling philosophy, which, if used, makes your programs easily

 PE> used in a client-server environment etc.  This is what I have documented.

 PE> The actual "minimal implementation" which I have used, is
not documented

 PE> at all (partly because I didn't want it to be confused with the general

 PE> philosophy).  I don't really know the best way of documenting that.



I think the best approach would be to document what your current minimal
implementation does. You can then document what you think is the ideal
error handling system, but it should be kept seperate from the current
implementation.



 PM>> It's biggest problem is that messages have to be defined in a central

 PM>> location. They are defined by using assembler macros and the whole thing

 PM>> is assembled into a load module and put in the link list. There was

 PM>> also another table listing which routines could issue which messages. As

 PM>> far as I can tell, this was done as a sort of forced documentation. If

 PM>> we ever needed to change a message, then we could track down all

 PM>> the programs using it.



 PE> Sounds more like a lousy implementation than a bad interface spec.

 PE> Pretty pointless having enforced documentation if it makes the routines

 PE> useless.



Apart from the hassle defining messages, the system works exceptionally
well. We have a lot of programs (more than 100) that do use it, but lately
we seem to have got out of the habit. Admittedly, we haven't written much
code over the past couple of years, so this may also account for part of
it's decline.



It is possible to use these routines on the mainframe side of a
client/server system, you can stack messages and retrieve them from the
buffer, you can deliver the messages to any DD name and/or the job log.
Considering that it was written about seven years ago, it is quite a far
sighted system.



 PM>> One thing we always did which is worth doing if you take this approach

 PM>> is to include the routine name in any messages issued. This really helps

 PM>> when you have some program deep in the guts of a system that is

 PM>> complaining. Much easier to get a message saying



 PM>> ABC1234E Getmain failed (SOMEPGM)



 PM>> than just



 PM>> ABC1234E Getmain failed.



 PE> Well the routine in this case would be "mMalloc", which
isn't going to

 PE> help you much either.  And if it wasn't, then I don't see why you can't

 PE> just do a search for the string of interest.



Yeah, getting "mMalloc" is not very helpful. What you need is to
get the routine than called it. The reason for suggesting this was this in
our system, messages are common. Any number of programs can use the same
message.



If you do a search for the string you want, you are still going to get
"mMalloc", which doesn't help you figure out who called it.



 PM>> Last time I checked fclose() was in the packet sorted I'm currently

 PM>> writing :-) This is also the first time I've ever done it :-)



 PE> What made you go to the effort of doing that?



I was writing a file class that encapsulated all the file handling
routines. I thought that I'd better do the right thing and check for any
errors. This then raised the problem of what to do when there was an error,
which is what made me look at your error handling in the first place :-)



 PM>> The other approach, which is what C++ is doing, is to use exceptions. I

 PM>> have seen some C implementations of exceptions but haven't tried any.



 PE> Want to post a brief description of exceptions here?  BFN.



Some example code is probably the best way of showing this.



In a traditional program you would code something like the following. It
doesn't matter whether the error flag is return from the function or set as
a global as you are doing, you have error tests all through the code.



    func1();

    if (error)

        ...

    else

        func2()

        if (error)

            ...

        else

            func3()

            if (error)

                ...



The C++ way with exception would be



    try

        {

        func1();

        func2();

        func3();

        }

    catch(some type)

        ...

    catch(some other type)

        ...



A 'try' block indicates that you are willing to handle (or catch) any
exceptions that occur in that block (the C++ term is to 'throw' an
exception). Any routine in the try block, or any routine that they call can
throw an exception. If nothing further down handles it, or it the handler
just passes it back up, then this code with handle it. It could in turn
decide it can't do anything about it and pass it back up the it's caller.



In C++ you can throw any type of variable, whether it's a built in or user
defined. On the catch clause, you specify the type you will handle. You
could have the following code in you program:



    throw("Error");



and



    throw(ERROR);  where ERROR is an int.



Your catch clauses would then be:



    catch(char *x);

    catch(int x);



In C++ I can see some advantages to doing it this way. I'm not convinced
that this is the correct approach for a C program. It would be interesting
to get one of the C implementations and play with it for a while.



Paul



--- GoldED/2 2.42.G1114

* Origin: It's life Jim, but not as we know it (3:711/934.1)
SEEN-BY: 635/514 640/305 711/809 934
@PATH: 711/934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.