From: wij on
On 6月4日, 上午3時39分, red floyd <redfl...(a)gmail.com> wrote:
> 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
>
> }
>

For the revised example program to work. Those thrown objects nearly
have to be unique to the extent that no other function can throw the
same error.

try { receive(msg); }
catch(receive_error_invalid_argument& e) {
// msg is not necessarily invalid,
// if e is not explicitly thrown by receive(..), e.g. some function
// inside receive(..) throw the same type,
}


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

From: wij on
I used std::exception to denote classes of std::exception family
for simplicity but caused confusion.
Sorry didn't make the subject clear,

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

>From the function (receive) document we know we can determine what
went wrong. But throwing this semantics is, as the title says
'is potentially buggy', Unless the function implementation catch all
thrown types and make it its responsibility.


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

From: Francis Glassborow on
wij(a)seed.net.tw wrote:
> On 6月3日, 上午4時06分, Francis Glassborow
> <francis.glassbo...(a)btinternet.com> wrote:
>> w...(a)seed.net.tw wrote:

>> 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.
<snipped>

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

To create tailor made exception classes that might or might not be
derived from the Standard ones. The Standard ones were generally
intended for use by the Standard Library.

When writing a library, (either general or for a specific application) I
normally create a suitable set of exception classes specifically for
that code.

BTW one of the serious issues with returning error codes is that they
frequently have to be relayed upwards until code that knows what to do
is reached. Error codes are fine if you expect the calling function to
handle the problem and just plain buggy if not.


Now consider a function that calls two functions both of which can fail
with an error code return but that cannot directly handle either
problem. If you use error returns you start getting ever more
complicated error handling as each successive function up the call stack
has to decide what the error return meant and wether it can handle it or
needs to relay it upwards. With exceptions all this is handled simply
and transparently.




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

From: Thomas Richter on
Francis Glassborow wrote:

> BTW one of the serious issues with returning error codes is that they
> frequently have to be relayed upwards until code that knows what to do
> is reached. Error codes are fine if you expect the calling function to
> handle the problem and just plain buggy if not.

While I'm with you mostly - use exceptions instead of return codes to
report errors - my experience in the C++ projects I worked on in the
last years is somewhat different - I'm designing and implementing
specialized image compression libraries, maybe that's a bit special, but
let it be as it is:

*) Most of the time, if an error happens, the code - my code - cannot do
*anything* about the problem. That is, in probably ~70% of the cases,
the error had to be reported *all* levels upwards, where it was then
converted to a C return code to supply data to a legacy C interface.

*) To a smaller degree, errors could be handled locally (~20-25%) and no
exception was required.

*) In the smallest amount of cases, errors reported by one level in the
code could be handled in another level in the code. IIRC, in the latest
250.000 lines code, I had about one or two cases where it mattered and
this approach was useful.

I only want to stress the attention to the fact that the old argument of
"throwing an exception is useful so another level of the code can handle
it" seems not to be quite true for my application domain. Most of the
time, I need to handle and can handle problems *immediately*, or I
cannot handle them at all.

As a "war time story" why that still makes exceptions useful, here's my
experience from a C (only) code from a second vendor whose name shall
better remain unmentioned: Here, return codes had been (or should have
been, rather) used to report errors from the lowest level to the highest
calling level. And of course, this error forwarding has been forgotten
in many places, resulting in code that is unstable, leaks memory or
works on invalid data in case of trouble.

Exceptions are pretty useful. But for me not exactly for the reason you
mentioned. It makes code easier to read, and it makes error forwarding a
lot easier. But I rarely forward errors to have them handled "upwards",
but to report them "upwards", interrupting all of *my* work without
leaking resources or keep working on stale data. Most of the exceptions
I throw cannot be safely resolved in any sane way. Not that I want to
abort the program, but rather inform the caller "this data is simply
invalid. Cannot decode, stop here."

Greetings,
Thomas

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

From: Mathias Gaunard on
On 4 juin, 15:34, Francis Glassborow
<francis.glassbo...(a)btinternet.com> wrote:

> Now consider a function that calls two functions both of which can fail
> with an error code return but that cannot directly handle either
> problem. If you use error returns you start getting ever more
> complicated error handling as each successive function up the call stack
> has to decide what the error return meant and wether it can handle it or
> needs to relay it upwards. With exceptions all this is handled simply
> and transparently.

I thought it was fairly complicated, but actually it isn't that much
if you still use destructors. Simply return as soon as you have an
error and everything still gets cleaned up properly.

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