Throwing error is potentially buggy

G

Goran

It seemed to me you are talking about inspecting the thrown object
dynamically for real errors is the correct way.

Hmmm... No, not necessarily. Exception object IMO should carry good
info about the original error, and should rarely be "inspected".
Exceptions work well in situations where it's useless to try to
continue running the started operation (that does not necessarily mean
"useless to run the whole program"). They should signal what could not
be done, and somewhere high up the stack, they should be used to
inform the user/operator what failed. Occasions where it's needed to
"inspect" them in order to take further action (corrective action?
perhaps) should be rare. If your code has that need, I'd say, derive a
specific exception type, so that you can catch that type specifically.
Then you know what's inside and why was it thrown.
I switch to normal codes because this can serve as a hint to the
answer of the other thread. (But I am not familiar with standard
library, I use mine.)

std::vector<T> v1,v2;
.....
try { v1.insert(itr,v2); }
catch(const std::invalid_argument& e) {
 // Run-time check e for the real meaning, never by type.}

catch(const std::length_error& e) {
 // Run-time check e for the real meaning, never by type.

};

Again, the code you put here is in my opinion completely wrong. Both
invalid_argument and length error signal programming errors (they both
derive from logic_error). It is therefore useless to catch them the
way you've shown. Frankly, it's not the first time I, and others, tell
you "that's not what you should do", and you continue to say "it's
broken if I do it".

What you should instead do, is let all your logic_error exceptions
propagate up to the highest possible stack level (e.g. main), catch
and terminate there (you could inform the operator/user that you
encountered a bug in the program). And perhaps not even that, perhaps
you should just let unhandled exception terminate the program (but
then, it's less clear what happened).

Why like this? Because logic_error means there is a bug in program
(and if it does not mean that, then the bug is that logic_error is
thrown when it should not have been thrown).

Goran.
 
W

wij

Hmmm... No, not necessarily. Exception object IMO should carry good
info about the original error, and should rarely be "inspected".
Exceptions work well in situations where it's useless to try to
continue running the started operation (that does not necessarily mean
"useless to run the whole program"). They should signal what could not
be done, and somewhere high up the stack, they should be used to
inform the user/operator what failed. Occasions where it's needed to
"inspect" them in order to take further action (corrective action?
perhaps) should be rare. If your code has that need, I'd say, derive a
specific exception type, so that you can catch that type specifically.
Then you know what's inside and why was it thrown.





Again, the code you put here is in my opinion completely wrong. Both
invalid_argument and length error signal programming errors (they both
derive from logic_error). It is therefore useless to catch them the
way you've shown. Frankly, it's not the first time I, and others, tell
you "that's not what you should do", and you continue to say "it's
broken if I do it".

What you should instead do, is let all your logic_error exceptions
propagate up to the highest possible stack level (e.g. main), catch
and terminate there (you could inform the operator/user that you
encountered a bug in the program). And perhaps not even that, perhaps
you should just let unhandled exception terminate the program (but
then, it's less clear what happened).

Why like this? Because logic_error means there is a bug in program
(and if it does not mean that, then the bug is that logic_error is
thrown when it should not have been thrown).

Goran.

If runtime_error is used instead in the example above, what's the
difference?

It is that I am just saying one thing that "throwing error is
potentially buggy" from the very beginning. While people kept saying
in various ways either the coding is itself buggy, logically
invalid, unqualified or it should be done differently, to make me
wrong or else. Should I do this or do that is not the central topic,
which is again "throwing error is potentially buggy", particularly it
occurs throughout the standard library, most of them are low-level
functions, you have not shown any real remedy for that but diverse
the focus (from my view). I don't really want to talk about standard
library's fatal problem (not really fatal, if they are mostly
indicating programming errors themselves as you have demonstrated).

A skim of my remaining C++ teaching language books, including Bjarne
Stroustrup's and Herb Sutter's, all sample programs advocating
throwing errors (exception), no major returning error codes were found
.. Many real programs in sourceforge can verify this, So I am in the
impression that the prevailing style is throwing errors.

Refer to [The C++ Programming Language, special edition, by
Bjarne Stroustrup] chapter 14, Exception Handling.

A quick snippet from [Programming Principles and Practice Using C++,
Bjarne Stroustrup,p144]
... The fundamental idea is to separate detection of an error
(which should be done in the called function) while ensuring
that a detected error cannot be ignored; that is, exceptions
provide a mechanism that allows us to combine the best of the
various approaches to error handling we have explored so far.

On the next page:
class Bad_area {};
int main() try {
int x=-1;
int y=2;
int z=4;
//.....
int area1=area(x,y);
int area2=framed_area(1,z);
int area3=framed_area(y,z);
double ratio=area1/area3;
}
catch(Bad_area) {
cout << "Oops! bad arguments to area()\n";
}

I don't believe you don't know the mentioned style of throwing
errors is popular and do not know where the idea is from. After all
however, I myself have no problem with the demonstrated example, I
use mine, since I regard the C++ exception theory as shit. The
problems arise when there are new programmers asked the related
issue. There is need to tell them the real thing.
Are you people the same?
 
G

Goran

If runtime_error is used instead in the example above, what's the
difference?

Yeah, fair enough ;-). You could use runtime_error, but it's probably
not the best idea. You should derive your exception classes from it.
As mentioned before, your derivation hierarchy should be wide, but not
deep.

Look at things this way: when there is an error (a real runtime error,
not programming error ;-)), what do you want your code to do? Most of
the time, you want to terminate a large chunk of processing as easy as
possible. Exceptions give you that in an easy way: you make a giant
try/catch, and catch errors somewhere at the far end of the operation.
You also probably want to inform your user what went wrong - using
std::exception::what() is there for it.
It is that I am just saying one thing that "throwing error is
potentially buggy" from the very beginning. While people kept saying
in various ways either the coding is itself buggy, logically
invalid, unqualified or it should be done differently, to make me
wrong or else.

I am sorry if that was your impression. It was not my intention to
make your point seem wrong, but to point out why your code snippets
are wrong. I mean, you really had a wrong approach in there, and you
got quite a few details completely wrong. Well, wrong code is wrong
irregardless of the use of exceptions.
Should I do this or do that is not the central topic,
which is again "throwing error is potentially buggy", particularly it
occurs throughout the standard library, most of them are low-level
functions, you have not shown any real remedy for that but diverse
the focus (from my view). I don't really want to talk about standard
library's fatal problem (not really fatal, if they are mostly
indicating programming errors themselves as you have demonstrated).

In my experience, if you receive an exception from standard library,
it's either bad_alloc, or an indication of a programming error (e.g.
range_error, stuff like that). I honestly see no problem whatsoever in
any exception thrown from standard library, hence there should be no
remedy. If it's a bad_alloc, well, you are out of memory, only thing
you can do is clean up while going up the stack and inform the user
that there's no memory - that's your remedy for bad_alloc. If it's
logic_error, there's a bug and it should be fixed by funding out
what's wrong and changing the code - that's your remedy for bugs.

What other remedy do you expect?
A skim of my remaining C++ teaching language books, including Bjarne
Stroustrup's and Herb Sutter's, all sample programs advocating
throwing errors (exception), no major returning error codes were found
. Many real programs in sourceforge can verify this, So I am in the
impression that the prevailing style is throwing errors.

Yes, in C++, it is. Situations where using error-return is interesting
are IMO seriously rare. Also, if you are using standard library, you
already work with exceptions. Many other C++ libraries, e.g. boost,
use exceptions to signal errors. So the reality is that you simply
can't escape exceptions with C++. operator new throws bad_alloc, STL
requires throwing operator new to work properly, simplest of things
like str1=str2+str3 might throw etc.

So you might try to use C++ libraries, but turn your own code into
error-return, but that would pretty much mean wrapping any function
you write, that use standard library and other libraries into giant
try/catch, and then turning that into error-return of your choosing.
That is IMO completely unwarranted and would result in a horrible
code.

Or, you may try to do C++ without exceptions, but then, for the code
to be "correct", it should not use standard operator new, standard
containers, string class and probably much more. Why would anyone
bother doing that is beyond me.

Goran.
 
Ö

Öö Tiib

Yes, in C++, it is. Situations where using error-return is interesting
are IMO seriously rare. Also, if you are using standard library, you
already work with exceptions. Many other C++ libraries, e.g. boost,
use exceptions to signal errors. So the reality is that you simply
can't escape exceptions with C++. operator new throws bad_alloc, STL
requires throwing operator new to work properly, simplest of things
like str1=str2+str3 might throw etc.

It is maybe important to note here that on case of most erasing,
releasing, freeing, closing and cleaning up operations it is generally
considered wrong to throw exceptions. These are not too rare in any
software that has truly dynamic data. Since throwing exceptions from
such operations is wrong the operations have to signal about success/
failure by other means.
 
W

wij

Yeah, fair enough ;-). You could use runtime_error, but it's probably
not the best idea. You should derive your exception classes from it.
As mentioned before, your derivation hierarchy should be wide, but not
deep.

Look at things this way: when there is an error (a real runtime error,
not programming error ;-)), what do you want your code to do? Most of
the time, you want to terminate a large chunk of processing as easy as
possible. Exceptions give you that in an easy way: you make a giant
try/catch, and catch errors somewhere at the far end of the operation.
You also probably want to inform your user what went wrong - using
std::exception::what() is there for it.


I am sorry if that was your impression. It was not my intention to
make your point seem wrong, but to point out why your code snippets
are wrong. I mean, you really had a wrong approach in there, and you
got quite a few details completely wrong. Well, wrong code is wrong
irregardless of the use of exceptions.


In my experience, if you receive an exception from standard library,
it's either bad_alloc, or an indication of a programming error (e.g.
range_error, stuff like that). I honestly see no problem whatsoever in
any exception thrown from standard library, hence there should be no
remedy. If it's a bad_alloc, well, you are out of memory, only thing
you can do is clean up while going up the stack and inform the user
that there's no memory - that's your remedy for bad_alloc. If it's
logic_error, there's a bug and it should be fixed by funding out
what's wrong and changing the code - that's your remedy for bugs.

What other remedy do you expect?


Yes, in C++, it is. Situations where using error-return is interesting
are IMO seriously rare. Also, if you are using standard library, you
already work with exceptions. Many other C++ libraries, e.g. boost,
use exceptions to signal errors. So the reality is that you simply
can't escape exceptions with C++. operator new throws bad_alloc, STL
requires throwing operator new to work properly, simplest of things
like str1=str2+str3 might throw etc.

So you might try to use C++ libraries, but turn your own code into
error-return, but that would pretty much mean wrapping any function
you write, that use standard library and other libraries into giant
try/catch, and then turning that into error-return of your choosing.
That is IMO completely unwarranted and would result in a horrible
code.

Or, you may try to do C++ without exceptions, but then, for the code
to be "correct", it should not use standard operator new, standard
containers, string class and probably much more. Why would anyone
bother doing that is beyond me.

Goran.

Anyway, thank you for tolerated my bad English and share of your
opinion about the new type of error(programming error).
If I now understand you better. It may be from different stance and
wording from different aspect of the same thing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top