comp.lang.ada
 help / color / mirror / Atom feed
From: David Marceau <davidmarceau@sympatico.ca>
Subject: Re: Error-names.
Date: Sun, 29 Feb 2004 14:56:21 -0500
Date: 2004-02-29T14:56:21-05:00	[thread overview]
Message-ID: <404243E5.376C42BB@sympatico.ca> (raw)
In-Reply-To: er19h1-f51.ln1@martinkl.dialup.fu-berlin.de

Martin Klaiber wrote:
> 
> David Marceau <davidmarceau@sympatico.ca> wrote:
> 
> > The Ada idea from my understanding is to make it robust by separating all the
> > different kinds of errors and dealing with each appropriate based on its
> > context.  The C style confuses and leaves you to wonder what the hell happened
> > and what exactly was the root of the cause.
> 
> I'd say, this depends on the elaboration of the return values.  Just
> returning a value /= 0 for any error is quite poor indeed.  But if one
> returns a specific value for each kind of error, the calling C-program
> should be as capable as an Ada-program finding out the cause of failure.
> 
> > The other thing about it is that because each case isn't handled
> > separately the cleanup that one is supposed to handle for every
> > different exception is not handled.
> 
> Well, perhaps this is a misunderstanding.  The example in my previous
> post is just an example.  In reality I distinguish between more
> exceptions.
> 
> > SUGGESTION
> > -----------
> > don't use when others all the time.
> 
> I agree.  General_Error is a fallback, as I must ensure that any
> exception is turned into a return-value, as the calling C-programm
> cannot deal with the Ada-exceptions.
> 
> In other parts of the library, for instance in the part where I
> evaluate the tax-year, I don't use 'when others' to make sure that I
> really handle every year for every case.
> 
> > make sure when others is used it is logged somewhere.
> 
> Hm, sorry, I don't understand what you mean here.
I just mean the reason you use "when others" in the first place is because it is
an exception you never thought about when designing the component.  You have to
admit when this happens whatever happens in a "when others" you have to document
and figure out in what context the situation occurred in order to go back and
add more code and maybe a new exception type to raise :)  The best way is to
first catch it into a file in order to come back and read about it...hence
logging the "when others" exception.  I think you already understand this kind
of thing but I voiced it out anyways just in case.  A perfect application should
not ever get into the part of the code inside "when others" at run-time.  That
said "when others" has to exist to catch a real exception and log the real
exception to enable us programmers to analyze what the problem is later to be
able to fix it ASAP.  That's my opinion.  Please correct me if I'm wrong.

> 
> > don't return integers in exception handlers.
> 
> I only do it for the functions called by the C-program.
> 
> > it's ok to raise another more specific exception to a higher level.
> 
> > The special case
> > ----------------
> > If you are writing a bridge that is controlled by C executable accessing an ada
> > shared library then yes there may be a real reason to return constants for
> > errors.
> 
> Yes, that's what I'm doing here.  The library has two interfaces, one
> for Ada-programs and one for C-programs.  The Ada-interface is doing
> no exception-handling at all.  All exceptions are passed to the calling
> Ada-program.
Now your strategy does make sense.  Just make sure all your Ada exceptions are
handled in the ada shared lib.
Ada Exceptions and C Exceptions don't seem to use the same default cleanup
strategies so you have to be very careful.
To protect your C executeable, make sure you have wrappers in a bridge/API on
the ADA side that actually does the calling to the real Ada service API.  In
that manner, you have a better chance at catching and logging your exceptions in
a textfile/database.

> 
> But for the C-interface I have to ensure that the calling program can
> handle errors and the library is not quitting execution by itself when
> an error occurs.  As C can't deal with Ada-exceptions, I turn them into
> return-values.  If there is a better way to do so, I'll happily use it.
> 
> > Feel free to add other special cases if you want but I'm pretty sure this is the
> > right direction to go instead of just porting a C mentality.
> 
> I don't see that I'm porting a C mentality.  I am no expert, neither in
> Ada nor in C, although my C is worse ;-)  But AFAIK return-values are
> the standard way to tell a C-program that a function failed.  Correct
> me if I'm wrong.
As you stated in a C program returning a constant value for the error is
standard "C" practice.
From what I understand, returning nothing and placing valuable information in an
"in out" parameter is more Ada95.
The valuable information I talking about is an object holding a structure of a
bunch of structures.
The advantage of this programming lifestyle which I learned from OLE(windows
programming lifestyle oddly enough) is it permits the service API to attain a
certain maturity quite quickly and focuses on limits change to services
affecting only one object.
The pattern of what I'm talking about in C is
void somefunc( OLEORWINDOWSORJNIHANDLEOFSOMESORT, ObjectToWorkOn);
i.e. setParmsForService1(ditto)
     callService1(ditto)
It may seem longer but it's not.
It may slow down the app a bit, but it makes the application much more
maintainable than having to deal with something like:
void
someComplicatedObfuscatingServiceWrittenBySomeAssholeWizardNotWantingToShareHisKnowledge(
SOMEHANDLEWHATEVER,
OBJECT,
parm1,
p2,
z3,
o4(what the hell is o4),
p65,
qwer7,
areYouStartingToUnderstandWhereImComingFrom8);

What I just wrote is very common in vb/c/C++/perl/java land.  Bad Code and
inherited C style is what that is.
Yes I've seen some bad ada code too.
Now focus on what it should look like in Ada:

procedure setParametersForServiceX
(
OLEORWINDOWSORJNIHANDLEOFSOMESORT
, ObjectToWorkOn
, ObjectHoldingParametersToPassToObjectToWorkOn
);

procedure callServiceX
(
OLEORWINDOWSORJNIHANDLEOFSOMESORT
, ObjectToWorkOn
);

My variable names and declarations are not Ada standard or C standard but what's
important is the placement of parameters and the number of parameters in the
service calling pattern to facilitate long term maintenance.  The rule of thumb
is there should be no more than three parameters in setParametersForService and
no more than two parameters in callService.
There could be some other pattern services to write for errors and logging and
stuff but the idea is reducing the number of parameters in each service makes
the services much more maintainable in the long term.
Throw me any service and I can justify that the thing doesn't have to be
complicated and should follow the above pattern.
Notice how I didn't show the type for these.  That's up to you but in my opinion
it usually is like a C++ reference where you can't change the actual address of
the object but everything inside it is definitely up to you if you want it to
muteable or not.

I don't know if you'll notice but there's a bit of assembler programming
influence in my source code format listing.
I only have one or two and at max three things of code and maybe a following
comment on each line.
Also notice one line for the opening brace/parentheses and another line for
closing brace/parentheses.  Call me crazy but I think it is most legible this
way.  It also helps you do focus on one problem at a time for each line.  I
follow the same style for if statements and everything else.  Sure it takes a
bit more time but in the long run it's better in my humble opinion.

I'd love to hear what others think about this.  I'm all ears.



  reply	other threads:[~2004-02-29 19:56 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-28 12:58 Error-names Martin Klaiber
2004-02-28 13:35 ` Error-names Martin Dowie
2004-02-28 15:26   ` Error-names Martin Klaiber
2004-02-28 17:19     ` Error-names Marius Amado Alves
2004-02-28 18:31       ` Error-names Martin Klaiber
2004-02-28 19:47         ` Error-names tmoran
2004-02-28 20:29           ` Error-names Martin Klaiber
2004-02-29 19:03           ` Error-names Jeffrey Carter
2004-02-29 20:04             ` Error-names tmoran
2004-02-29 23:24               ` Error-names Björn Persson
2004-03-01 11:29                 ` Error-names Martin Klaiber
2004-03-01 12:48                   ` Error-names Marius Amado Alves
2004-03-02  2:15                     ` Error-names Jeffrey Carter
2004-02-29 20:33             ` Error-names Martin Klaiber
2004-02-29 23:43               ` Error-names tmoran
2004-03-01 11:20                 ` Error-names Martin Klaiber
2004-03-07 15:10                   ` Error-names Björn Persson
2004-03-08  5:42                   ` Error-names Dave Thompson
2004-02-28 20:26         ` Error-names Jacob Sparre Andersen
2004-02-28 18:29 ` Error-names Alexandre E. Kopilovitch
2004-02-29  5:30 ` Error-names David Marceau
2004-02-29 12:17   ` Error-names Martin Klaiber
2004-02-29 19:56     ` David Marceau [this message]
2004-02-29 21:57       ` Error-names Martin Klaiber
2004-03-01 23:20       ` Error-names Randy Brukardt
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox