From: wij on
On 6月3日, 上午4時06分, Francis Glassborow
<francis.glassbo...(a)btinternet.com> wrote:
> w...(a)seed.net.tw wrote:
> >>From a different site, a programmer asked for proper coding standard
> > (error handling) for a common program scenario:
>
> > initialize();
> > while (true) {
> > Message msg,out;
> > receive(msg);
> > process(msg,out);
> > send(out);
> > }
>
> > I thought it would be very difficult to throw std::exception classes
> > to handle all thinkable possible exceptional condition. This opinion
> > has wide
> > effect to C++ programs.
>
> > My argument is that the catch handler won't be able to tell what had
> > actually
> > happened and handle it properly. E.g.
>
> > initialize();
> > while(true) {
> > try {
> > Message msg,out;
> > try { receive(msg); }
> > catch(const std::exception& e) {
> > // Instead of rethrow or ignore, what can be done here reliably
> > to handle
> > // std::exception or others?
> > }
> > process(msg,out);
> > send(out);
> > }
> > catch(const std::exception& e) {
> > // Instead of rethrow or ignore, what can be done here reliably to
> > handle
> > // std::exception or others?
> > }
> > }
>
> > Say if I caught std::invalid_argument from receive(msg), does it
> > really mean
> > msg is invalid? The same argument for others e.g.
> > domain_error,length_error,
> > out_or_range,range_error,overflow_error,.., and underflow_error.
> > If the std::invalid_argument is caught in the second catch handler
> > above,
> > the picture would be even more complex.
>
> > So a coding standard forbids using throw and favors return is simply
> > practical
> > from this point view. Instead, most programs using throw is
> > potentially
> > buggy.
>
> You have not made your case. If you can return an error code you can
> throw and equally descriptive object (actually good design will allow
> the object to be more descriptive. BTW only the most naive programmer
> thinks that exceptions are limited to the standard exception classes.
>

This is a general reply. All above you people said require the program
(actually, all functions in the program) catch all thrown objects for
the error handling mechanism to work properly. In the case of return
, it is simply the responsibility of the function implement.
But I assumed the already general practice: thrown object can be
legally missed and caught in a top-top function. Isn't is true it
can
be mis-interpreted?

For Francis Glassborow, if it is the most naive programmer using
only std::exception, then what's the practical alternative coding
standard?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Nick Hounsome on
On 2 June, 14:51, w...(a)seed.net.tw wrote:
> >From a different site, a programmer asked for proper coding standard
>
> (error handling) for a common program scenario:
>
> initialize();
> while (true) {
> Message msg,out;
> receive(msg);
> process(msg,out);
> send(out);
>
> }
>
> I thought it would be very difficult to throw std::exception classes
> to handle all thinkable possible exceptional condition. This opinion
> has wide
> effect to C++ programs.
>
> My argument is that the catch handler won't be able to tell what had
> actually
> happened and handle it properly. E.g.
>
> initialize();
> while(true) {
> try {
> Message msg,out;
> try { receive(msg); }
> catch(const std::exception& e) {
> // Instead of rethrow or ignore, what can be done here reliably
> to handle
> // std::exception or others?
> }
> process(msg,out);
> send(out);
> }
> catch(const std::exception& e) {
> // Instead of rethrow or ignore, what can be done here reliably to
> handle
> // std::exception or others?
> }

As a general rule "Don't catch exceptions if you don't know what to do
with them".
or
"Catch execeptions in the smallest scope that knows how to handle
them".

There is no way that you can know that it is safe to continue from
this point hence your only real option is to terminate.

In my experience the best way to handle exceptions at a low level in
this sort of message passing system is by using "Double Dispatch" to
regain the message type information.

Another option is the rethrowing trick: call a virtual
msg.HandleException() called from your catch block (move msg out of
the try block first). This method can rethrow the current exception
"try { throw; }" and catch it again but with appropriate handlers
allowing for message specific handling of exception types that the
specific message type expects.




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
wij(a)seed.net.tw wrote:
> All above you people said require the program (actually, all functions
> in the program) catch all thrown objects for the error handling
> mechanism to work properly. In the case of return, it is simply the
> responsibility of the function implement.

Well, with exceptions, the default is to propagate them to up the call stack
to some code that handles it. With return codes, the default is to not
propagate or handle them at all. For anything other than the default, you
have to manually write code in both cases. I'd say that errors should
generally not be ignored, so the default of propagating errors without
writing extra code is better for me.

BTW: Your example is mostly useless. The point is that you left out the
important part, i.e. the error handling. If you want to discuss this,
provide a more realistic example, where you also demonstrate how you want
different errors handled. People could then help you translate this into
the most elegant form that uses exceptions or tell you if they are even the
right tool for the job. As it is now, I don't know what could go wrong, so
I also can't tell you how to handle it. Generally, guessing from your code,
if an error occurs in one of the transactions (receive, process, reply),
there is no use continuing, so I would probably wrap the whole transaction
in a try-catch-clause, maybe even leave the while() loop in case of errors.


> But I assumed the already general practice: thrown object can be
> legally missed and caught in a top-top function. Isn't is true it
> can be mis-interpreted?

I don't think I understand what you mean here. You generally don't catch
exceptions close where they happen but rather on a higher level. Close to
where they happen, you usually can only rethrow them and not handle them.
If you can't handle them there, you don't and let them propagate upwards.

> For Francis Glassborow, if it is the most naive programmer using
> only std::exception, then what's the practical alternative coding
> standard?

Using an exception type derived from std::exception is the generally
accepted standard. Also, Francis didn't say "std::exception" but "standard
exception classes", which includes a few more. In practice, I often find
myself deriving from std::runtime_error.

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: red floyd on
On Jun 3, 6:30 am, w...(a)seed.net.tw wrote:

> But I assumed the already general practice: thrown object can be
> legally missed and caught in a top-top function. Isn't is true it
> can
> be mis-interpreted?

Only if you don't catch it. See sample below.

>
> For Francis Glassborow, if it is the most naive programmer using
> only std::exception, then what's the practical alternative coding
> standard?
>

Derive from std::exception, and throw those

e.g.:

class receive_error : public std::exception { ... };
class send_error : public std::exception { ... };
class processing_error : public std::exception { ... };

initialize();
while (true) {
try {
Message msg,out;
receive(msg);
process(msg,out);
send(out);
}
catch (receive_error& e) {
// receive() barfed
}
catch (processing_error& e) {
// process() barfed
}
catch (send_error& e) {
// send() barfed
}
// other exceptions propagate out
}


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Goran on
On Jun 3, 3:30 pm, w...(a)seed.net.tw wrote:
> But I assumed the already general practice: thrown object can be
> legally missed and caught in a top-top function. Isn't is true it
> can
> be mis-interpreted?

Of course this is true. It's your job to make sure that you can
understand what said thrown object means, just like it's jor job to
make sure to understand what error-return means.

If you throw invalid_argument everywhere, you can't expect to know
what really went wrong.

Similarly, if you return EINVAL everywhere, you can't expect to know
what really went wrong just the same.

Here's a counter-example using error-return:

bool f0()
{
....
if (!f1()) return false;
if (!f2()) return false;
....
}

bool f1()
{
....
if (!f3()) return false;
if (!f4()) return false;
....
}

bool f4()
{
FILE* f = fopen()
if (!f)
return false;
}

int main(...)
{
if (!f0())
{
// How do you know here that e.g. fopen failed. Where? For what
file name?
}
}

> For Francis Glassborow, if it is the most naive programmer using
> only std::exception, then what's the practical alternative coding
> standard?

You derive many classes from std::exception (and other std:: classes).
You __don't__ throw std::exception everywhere. In fact, for your own
errors, you can hardly ever throw existing standard-defined classes,
simply because these are way too general (just like EINVAL is too
general). You need more info. So you derive. Derivation tree is
typically not deep, but wide.

Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]