But I'm afraid I still don't see if there is a consensus whether or not Exceptions are a Good Thing?
I found a lot of tips and discussion about the technicalities of exceptions, but the big question is From what I read, there seems to be a consensus that: 1. Writing exception-safe code is harder than without exceptions; 2. Excpetions introduce a second path of control flow "behind the scenes", which increases the complexity of the code; 3. In order to do decent error-handling in constructors, you must use exceptions.
So, my questions are: a) should I use exceptions only for constructors and error codes for all other methods? b) if exceptions are used in general, should functions return *only* error codes *or* throw exceptions? (i.e., is it ok to mix both in one method?) c) should exceptions be used only for "exceptional" cases, or could they also be used for not-so-exceptional things, like bogus parameters passed in from the caller?
All insights and pointers will be greatly appreciated. TIA, Gab.
-- /---------------------------------------------------------------------\ | Paradigm is a word too often used by those | | who would like to have a new idea | | but cannot think of one. | | (Mervyn King, Deputy Governor, Bank of England) | | | | z...@igd.fhg.de g...@gab.cx Gabriel.Zachm...@gmx.net | | www.igd.fhg.de/~zach/www.gab.cx __@/' | \---------------------------------------------------------------------/
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
To be honest I don't usually use them when coding. 99% of the time one can write code that handles error coditions gracefully (how we used to do it in the old days)..
However, I have found that many poorly designed class libraries use them a lot. In this situation one has to catch the exceptions thrown - MFC is a classic example of this..
The only case where they are indeed usefull is to prevent a critical exception that may force program termination.. In this case its often usefull to wrap the code with an exception then call your error handle to notify the user and roll back to a stable state.
Andy
On 11 Dec 2000 14:19:48 -0500, z...@igd.fhg.de (Gabriel Zachmann) wrote:
>But I'm afraid I still don't see if there is a consensus >whether or not > Exceptions are a Good Thing?
>I found a lot of tips and discussion about the technicalities of >exceptions, but the big question is > From what I read, there seems to be a consensus that: >1. Writing exception-safe code is harder than without exceptions; >2. Excpetions introduce a second path of control flow "behind the scenes", > which increases the complexity of the code; >3. In order to do decent error-handling in constructors, you must use > exceptions.
>So, my questions are: >a) should I use exceptions only for constructors and error codes for > all other methods? >b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > method?) >c) should exceptions be used only for "exceptional" cases, or could they > also be used for not-so-exceptional things, like bogus parameters passed > in from the caller?
>All insights and pointers will be greatly appreciated. >TIA, >Gab.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
z...@igd.fhg.de (Gabriel Zachmann) writes: > 1. Writing exception-safe code is harder than without exceptions;
True. However, whether you like it or not, exceptions are in the language and the WILL happen. The question is, will your code work when they do happen?
> 2. Excpetions introduce a second path of control flow "behind the scenes", > which increases the complexity of the code;
This path of control exiting "anywhere" already exists. Ignoring it does not make it go away.
> 3. In order to do decent error-handling in constructors, you must use > exceptions.
Yes, there is no other good way to indicate failure. Or, alternately, design objects such that construction CAN'T fail. Then you don't have to throw exceptions.
> So, my questions are: > a) should I use exceptions only for constructors and error codes for > all other methods?
Well, any exceptional situation where you know THAT an error occurred but you don't know HOW to handle it is a good candidate for exceptions.
I rarely throw them myself, but I try to write code that works if they do happen to get thrown. This is because my code is a middleware library, with user code calling into me, and I call back out into them through callbacks. So they can throw exceptions and my code really needs to continue working.
> b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > method?)
It's ok to mix, but have a consistent strategy. If your functions are internal to a subsystem, it doesn't matter how they INTERNALLY handle errors, and error codes are fine. (Your code knows about your other code.) Exceptions are generally better for cross-subsystem kinds of operations, where it is someone else's code that has to handle an error you detect. Or, if your code is seperated enough to where you don't want part of your code to know about error codes of another part of your application.
> c) should exceptions be used only for "exceptional" cases, or could they > also be used for not-so-exceptional things, like bogus parameters passed > in from the caller?
Never use them for not-so-exceptional things that can be handled better in other ways. Bogus parameters can indeed be VERY exceptional, it all depends on the application.
I throw an exception when I know that I've detected misuse of some code, especially if a user is doing it. If it's my own code misusing other parts of my code, then it's simply a bug and the assert macro is better at finding that.
-- Chris
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> But I'm afraid I still don't see if there is a consensus > whether or not > Exceptions are a Good Thing?
> I found a lot of tips and discussion about the technicalities of > exceptions, but the big question is > From what I read, there seems to be a consensus that: > 1. Writing exception-safe code is harder than without exceptions;
False. Writing exception safe code is easier than equivalent code written using return codes and conditional branches (and setjmp & longjmp).
What is true is that it requires a different coding style that many developers are unaware of.
> 2. Excpetions introduce a second path of control flow "behind the
scenes",
One needs to think about program state not control paths. For example, on exit from a function (either by return or exception) the destructors of all auto variables will have been executed.
> which increases the complexity of the code;
When using error returns the need for multiple test & branches introduces the same number of alternative paths. But they need to be managed manually - which increases code complexity.
> 3. In order to do decent error-handling in constructors, you must use > exceptions.
False. In the 1980's exceptions were not in the language and idioms were developed to accomplish this. In particular "Two Phase Construction" - the constructor didn't do anything that could fail, and the client code was required to call an "init()" member function before using the object.
Avoiding exceptions increases the complexity of both implementation and client code - but does allow "decent error-handling".
> So, my questions are: > a) should I use exceptions only for constructors and error codes for > all other methods?
No, use exceptions for operations that:
/1/ may fail but are expected to work (e.g. allocating resources) and /2/ are distant from "domain" code that reacts to the failure.
> b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > method?)
It is OK to mix them.
> c) should exceptions be used only for "exceptional" cases, or could they > also be used for not-so-exceptional things, like bogus parameters passed > in from the caller?
This is an edge case:
/1/ Do you want to document and test that exceptions are thrown for "bogus parameters"?
/2/ Do you want to specify valid parameters and leave the rest as "undefined behaviour"?
Both are valid approaches depending on your context.
> All insights and pointers will be greatly appreciated.
There is no concensus. Some people swear by them. Others swear at them.
> I found a lot of tips and discussion about the technicalities of > exceptions, but the big question is > From what I read, there seems to be a consensus that: > 1. Writing exception-safe code is harder than without exceptions; > 2. Excpetions introduce a second path of control flow "behind the scenes", > which increases the complexity of the code; > 3. In order to do decent error-handling in constructors, you must use > exceptions.
Add overloaded operators to 3, and you've summarized it pretty well. On the other hand, it's possible to design constructors so they don't fail, or so that you can check them afterwards (a la iostream), so it's not necessarily as big a point as is sometimes pretended.
And you missed:
4. Exceptions make the main body of the function simpler, so easier to write and to understand.
I don't think there is one true answer. Generally, I'm fairly sceptical of exceptions, but then, I'm sceptical of unproven solutions in general. *IF* you have a lot of cases where error detection is at a much lower level than error handling, exceptions can simplify the intermediate code significantly. On the other hand, they do create a whole new family of problems involving exception safety, and the make rigorous analysis of code flow more difficult. Which aspect weighs heaviest will vary according to the application and the organization.
Globally, I'd say that exceptions should not be used in a critical application, where human life is at stake. And of course, in a lot of simple applications (compilers, etc.), they're really irrelevant -- in exceptional cases, you just abort with an error message. For typical server applications, etc., however, they might have a place to abort an operation without killing the process.
> So, my questions are: > a) should I use exceptions only for constructors and error codes for > all other methods?
No. Be consistent.
> b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > method?)
Ditto.
> c) should exceptions be used only for "exceptional" cases, or could they > also be used for not-so-exceptional things, like bogus parameters passed > in from the caller?
I would hope that a bogus parameter is something really exceptional, if it comes from within my program. I wouldn't use exceptions for errors in user input, however.
-- James Kanze mailto:ka...@gabi-soft.de Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> I am trying to decide whether or not to use exceptions.
The only consensus of interest is then, IMO, the consensus of those who'll maintain the code.
>... > But I'm afraid I still don't see if there is a consensus > whether or not > Exceptions are a Good Thing?
Always depends on the application of the tool. Icepicks can be great, although not a Good Thing as murder weapons. Of course you mean as an error reporting mechanism, but even in that context there's room for application and misapplication.
>... > From what I read, there seems to be a consensus that: > 1. Writing exception-safe code is harder than without exceptions;
Meaningless or false.
(1) If there can be no exceptions, then the code is exception-safe.
(2) Otherwise, you *need* exception handling in order to make the code exception safe.
(3) With a more general interpretation, writing "error safe" code is distinctly easier using exception handling (that's the whole point of the mechanism).
> 2. Excpetions introduce a second path of control flow "behind the
scenes", which increases the complexity of the code;
First part is true, conclusion is generally false. Generally the complexity of the code is lowered because you can separate error handling from normal case code, and because you don't have to clutter the code with return value checking. Otoh. it's *possible* to increase the actual complexity of the code by lowering the apparent complexity, e.g. code that is structured to function correctly in the presence of exceptions but only because things get done in a certain order, and where this isn't documented.
> 3. In order to do decent error-handling in constructors, you must > use exceptions.
Generally this is false, but exceptions are way more convenient for this than other means (e.g. two-phase construction with Init method, reference error parameter or ditto global, error handling function, whatever). What you do gain is automatic deallocation, plus -- depending on the alternative considered -- removal of the possibility of using a non-properly constructed object. These advantages are so great that you'd need a very good reason *not* to use exceptions for error reporting from constructors (one such reason being the deallocation bug of Visual C++ 5.0 and earlier).
> ... > a) should I use exceptions only for constructors and error codes for > all other methods?
No. But that doesn't imply the opposite, that you should always use exceptions. Use sound judgement, considering always how your classes will or may be used. This call can be tough, since there is a "conflict of interest" present. At the lowest levels of the code where failures often occur, efficiency dictates return codes or some such scheme, while correctness guarantees dictates using exceptions (essentially this boils down to the guarantees you endowe your methods with; one solution is to have one set of "bare" error-code based functions and one set of "safe" exception-throwing wrappers).
> b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in > one method?)
Don't mix error reporting strategies. But you can use return codes for success reporting. Again, this boils down to the contracts you define for the methods, and designing those contracts can be hard.
> c) should exceptions be used only for "exceptional" cases, or could > they also be used for not-so-exceptional things, like bogus > parameters passed in from the caller?
First is easy: yes. Second part is false: bogus parameters *are* (or at least, should be) exceptional. I'd use exceptions for that.
Hth.,
- Alf
-- alf_DOT_steinbach_AT_ac_DOT_com (clean the address before replying)
> I am trying to decide whether or not to use exceptions.
Don't think of exceptions as being error handling constructs; think of them as program flow constructs. Just like a goto isn't automatically harmful or beneficial in C, using exceptions isn't automatically good one way or another in C++.
> 1. Writing exception-safe code is harder than without exceptions;
Untrue. Writing exceptionless code requires that you introduce functionality to handle exceptional states. One way or another, exception conditions occur and you'd better be equipped to handle them. If you don't like how new throws an exception on a bad memory allocation, you're free to use new(nothrow), but you'd better check for NULL after every allocation.
See what I mean? One way or another, error conditions must be checked for. Exceptions are oftentimes an elegant way to check for, and handle, these error states.
> 2. Excpetions introduce a second path of control flow "behind the scenes", > which increases the complexity of the code;
No. They change a second path of control flow, not add a new one. The original second path starts at an error state and leads straight to a coredump. With error handling (which may include exceptions as part of an intelligent error design), this catastrophic execution path can be redirected to a more graceful exit, or even have termination avoided altogether.
> 3. In order to do decent error-handling in constructors, you must use > exceptions.
Not necessarily. Consider:
class A { public: int errorstate; A(void) { errorstate = 0; // do more stuff here, traps an error errorstate = 1; return; // do more stuff here if no error trapped }
};
int main(int argc, char *argv[]) { A myfunc; if (myfunc.errorstate) { // do error handling stuff here
}
Note that I don't recommend doing things this way. But it does show that it's possible to do error handling in constructors without exceptions (even if it means just flagging a failure appropriately).
> a) should I use exceptions only for constructors and error codes for > all other methods?
Use them whenever they're appropriate. How will you know if they're appropriate? By using your experience. So get out and experiment around with exceptions some. :)
> b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > method?)
Just be consistent. If you do one, then only do that one. If you do both, then always do both. Etc.
> c) should exceptions be used only for "exceptional" cases, or could they > also be used for not-so-exceptional things, like bogus parameters passed > in from the caller?
Exceptions are not only useful for errors. Consider:
if (...) { if (...) { if (...) { if (...) throw myException(); // insert multiple closing brackets here
catch (myException &e) { .... etc.
}
.... In that above case, exceptions work as a better GOTO. Remember: exceptions /are just program control statements/. They aren't magically tied to error conditions.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
<snip> > So, my questions are: > a) should I use exceptions only for constructors and error codes for > all other methods? > b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > method?) > c) should exceptions be used only for "exceptional" cases, or could they > also be used for not-so-exceptional things, like bogus parameters passed > in from the caller?
IMHO
a) no b) no. Use error codes for run of the mill errors and exceptions for catastrophic failures c) I agree with the first part
Adrian
P.S Your sig is too long.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
Chris Uzdavinis wrote: > z...@igd.fhg.de (Gabriel Zachmann) writes: > > 1. Writing exception-safe code is harder than without exceptions; > True. However, whether you like it or not, exceptions are in the > language and the WILL happen. The question is, will your code work > when they do happen?
That's not really true. The language supports exceptions, but it certainly doesn't require their use. The standard library only throws exceptions in a few specific cases, which it is possible to avoid.
> > 2. Excpetions introduce a second path of control flow "behind the scenes", > > which increases the complexity of the code; > This path of control exiting "anywhere" already exists. Ignoring it > does not make it go away.
It doesn't exist in most of the code I write.
> > 3. In order to do decent error-handling in constructors, you must use > > exceptions. > Yes, there is no other good way to indicate failure. Or, > alternately, design objects such that construction CAN'T fail. Then > you don't have to throw exceptions.
Designing constructors so they can't fail is often a good idea anyway.
> > So, my questions are: > > a) should I use exceptions only for constructors and error codes for > > all other methods? > Well, any exceptional situation where you know THAT an error occurred > but you don't know HOW to handle it is a good candidate for > exceptions. > I rarely throw them myself, but I try to write code that works if > they do happen to get thrown. This is because my code is a > middleware library, with user code calling into me, and I call back > out into them through callbacks. So they can throw exceptions and > my code really needs to continue working.
In general, writing exception safe code is probably a good idea. Because even if you don't use exceptions today, you might want to in the future.
> > b) if exceptions are used in general, should functions return *only* > > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > > method?) > It's ok to mix, but have a consistent strategy. If your functions > are internal to a subsystem, it doesn't matter how they INTERNALLY > handle errors, and error codes are fine. (Your code knows about > your other code.) Exceptions are generally better for > cross-subsystem kinds of operations, where it is someone else's code > that has to handle an error you detect. Or, if your code is > seperated enough to where you don't want part of your code to know > about error codes of another part of your application. > > c) should exceptions be used only for "exceptional" cases, or could they > > also be used for not-so-exceptional things, like bogus parameters passed > > in from the caller? > Never use them for not-so-exceptional things that can be handled > better in other ways. Bogus parameters can indeed be VERY > exceptional, it all depends on the application. > I throw an exception when I know that I've detected misuse of some > code, especially if a user is doing it. If it's my own code > misusing other parts of my code, then it's simply a bug and the > assert macro is better at finding that.
It depends a lot on the application.
Ideally, you'd probably like to cut the application up into a lot of little processes, so that an error in one (e.g. a bad pointer) can't propagate back into the others. If you do this, you're "exception" mechanism is called abort with an error message:-). In many cases, however, the price for doing this is too high. So you use exceptions for aborting what you'd really like to have in a separate process.
-- James Kanze mailto:ka...@gabi-soft.de Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> Designing constructors so they can't fail is often a good idea anyway.
Interesting statement. Clearly, designing _anything_ so it can't fail is a good idea. However, how does one manage this with constructors in particular? How does one design a constructor so that it doesn't care if the machine is out of memory, or if a needed file doesn't exist? The only answer is to push all that off onto another function that the client has to call. But what does that buy?
I guess I'd like more explanation of your statement.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
In article <3A361160.18BE8...@dresdner-bank.com>, James Kanze <James.Ka...@dresdner-bank.com> writes
>Globally, I'd say that exceptions should not be used in a critical >application, where human life is at stake. And of course, in a lot of >simple applications (compilers, etc.), they're really irrelevant -- in >exceptional cases, you just abort with an error message. For typical >server applications, etc., however, they might have a place to abort >an operation without killing the process.
Even if you choose never to use exceptions yourself, I think it is advisable to write exception safe code.
Francis Glassborow Association of C & C++ Users 64 Southfield Rd Oxford OX4 1PA +44(0)1865 246490 All opinions are mine and do not represent those of any organisation
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> > Designing constructors so they can't fail is often a good idea anyway.
> Interesting statement. Clearly, designing _anything_ so it can't fail is a good > idea. However, how does one manage this with constructors in particular? How > does one design a constructor so that it doesn't care if the machine is out of > memory, or if a needed file doesn't exist? The only answer is to push all that > off onto another function that the client has to call. But what does that
buy?
Easy.
Have the constructor do nothing.
Constructor() {
}
Then have an Init() function that does the actual initialization.
You asked.
It buys a big plus in some situations, delayed activation. Sometimes you are in situations where creation of temporaries is inevitable, for example, sticking something into an STL collection. In those cases, you like to have a lightweight constructor that doesn't actually do anything, for example, a file object that doesn't actually open the file, otherwise, even the creation of a temporary is going to open a file, destruction of the temporary will close it. Very wasteful, especially for disk access or network access. Imagine a "SocketConnection" class that, for every temporary, had to actually go out and contact the remote host.
Walt Howard
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
Even if you don't use exceptions, even one exception in your entire program or library you are using, causes the compiler to construct the proper stack frames. You are paying the cost anyway.
I think people should give a "no error code" program a try. Go all the way. Never have your functions return error codes, always have them throw an exception if they fail in their task. Really give exceptions a fair shot.
Then, when you've made a program work that way, you can decide which is really best, exceptions or error return codes. Until then, you are really just guessing.
Walt Howard
Francis Glassborow <francis.glassbo...@ntlworld.com> writes: > In article <3A361160.18BE8...@dresdner-bank.com>, James Kanze > <James.Ka...@dresdner-bank.com> writes > >Globally, I'd say that exceptions should not be used in a critical > >application, where human life is at stake. And of course, in a lot of > >simple applications (compilers, etc.), they're really irrelevant -- in > >exceptional cases, you just abort with an error message. For typical > >server applications, etc., however, they might have a place to abort > >an operation without killing the process.
> Even if you choose never to use exceptions yourself, I think it is > advisable to write exception safe code.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> Then, when you've made a program work that way, you can decide which > is really best, exceptions or error return codes. Until then, you are > really just guessing.
I'm learning COM right now. COM objects always return error codes. This in itself was interesting; I'm not used to returning a result code from a function that can only succeed, but it's nice and consistent.
The client of that COM object uses #import to call those COM methods. #import sets things up so that if any method of the COM object fails, it throws an exception. So COM clients (who use #import) must get used to the "all-exception" approach.
I do like "all-exception", however, I'd point out that even "all-error codes" is different than the way I'm used to programming.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
In article <slrn93a6ke.5e1p.z...@schwind.igd.fhg.de>,
z...@igd.fhg.de wrote: > So, my questions are: > a) should I use exceptions only for constructors and error codes for > all other methods?
I think the benefits of exceptions outweigh any complexities involved, and exceptions should replace error codes in general (with, um, a few "exceptions")
> b) if exceptions are used in general, should functions return *only* > error codes *or* throw exceptions? (i.e., is it ok to mix both in one > method?)
It's OK to mix, but IMO not as a general strategy. You might decide to do certain sets of conditions with return codes, and certain sets of conditions with exceptions. See below.
> c) should exceptions be used only for "exceptional" cases, or could they > also be used for not-so-exceptional things, like bogus parameters passed > in from the caller?
It depends - how bad are bogus parameters? For example, if you can do some reasonable default behavior if you get a bad parameter that wouldn't surprise the use, then maybe no exception is needed. The general guideline is to use exceptions when you cannot do, or finish, what you were asked to do, and don't use exceptions to do more than that.
> > > Designing constructors so they can't fail is often a good idea anyway.
> > Interesting statement. Clearly, designing _anything_ so it can't fail is a > good > > idea. However, how does one manage this with constructors in particular? How > > does one design a constructor so that it doesn't care if the machine is out > of > > memory, or if a needed file doesn't exist? The only answer is to push all > that > > off onto another function that the client has to call. But what does that > buy?
> It buys a big plus in some situations, delayed activation.
Sorry, I was asking with respect to exceptions. I'm aware of other advantages (and disadvantages) of this technique, but wanted to know how they relate to constructor failure.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> "James Kanze" <James.Ka...@dresdner-bank.com> wrote in message > news:3A3612BC.2474EFF@dresdner-bank.com... > > Designing constructors so they can't fail is often a good idea > > anyway. > Interesting statement. Clearly, designing _anything_ so it can't > fail is a good idea. However, how does one manage this with > constructors in particular? How does one design a constructor so > that it doesn't care if the machine is out of memory, or if a needed > file doesn't exist? The only answer is to push all that off onto > another function that the client has to call. But what does that > buy?
It means that you don't have to deal with exceptions coming from that constructor. If you defer anything that can fail to a later initialize function, you can handle a return code. If you use a factory, you can delete the object if the initialization fails, and return a null pointer. If on the other hand, you use an internal failure flag, like iostream, you can integrate the error handling into that of the normal case, again like iostream.
Globally, making it an absolute rule not to throw from a constructor only makes sense (to me) if you are designing to not use exceptions anywhere. But even in constructors, exceptions should only be used for exceptional cases, so you will occasionally have cases where other mechanisms are needed anyway.
-- James Kanze mailto:ka...@gabi-soft.de Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> However, how does one manage this with constructors in particular? > How does one design a constructor so that it doesn't care if the > machine is out of memory, or if a needed file doesn't exist?
Alan Griffiths wrote: > In article <slrn93a6ke.5e1p.z...@schwind.igd.fhg.de>, > z...@igd.fhg.de wrote: > > From what I read, there seems to be a consensus that: > > 1. Writing exception-safe code is harder than without exceptions; > False. Writing exception safe code is easier than equivalent code > written using return codes and conditional branches (and setjmp & > longjmp).
It's certainly false that this is a consensus opinion. Whether writing robust exception safe code is easier or is harder than the alternatives is very much a personal matter. I've been writing robust error handling code for over twenty years now, and I don't see where exceptions make my life easier. But that could at least in part be because I've ingrained habits which make the alternatives particularly easy. Or it could be because I've mainly worked on critical systems, where correct error handling is considered a fundamental part of the basic algorithm (and the algorithms are generally fundamentally pretty simple, so the added complexity due to error handling doesn't render them unmanageable).
> What is true is that it requires a different coding style that many > developers are unaware of. > > 2. Excpetions introduce a second path of control flow "behind the > scenes", > One needs to think about program state not control paths. For > example, on exit from a function (either by return or exception) the > destructors of all auto variables will have been executed.
The problem is that there is very little theoretical work to support program proofs based purely on program state, without regards to control paths.
> > which increases the complexity of the code; > When using error returns the need for multiple test & branches > introduces the same number of alternative paths. But they need to > be managed manually - which increases code complexity.
The number may actually be significantly less in practice. You always know when a component returns a return code; you may often not know in the case of exceptions, and you must be prepared to handle the worst case.
> > 3. In order to do decent error-handling in constructors, you must use > > exceptions. > False. In the 1980's exceptions were not in the language and idioms > were developed to accomplish this. In particular "Two Phase > Construction" - the constructor didn't do anything that could fail, > and the client code was required to call an "init()" member function > before using the object. > Avoiding exceptions increases the complexity of both implementation > and client code - but does allow "decent error-handling". > > So, my questions are: > > a) should I use exceptions only for constructors and error codes for > > all other methods? > No, use exceptions for operations that: > /1/ may fail but are expected to work (e.g. allocating resources) and > /2/ are distant from "domain" code that reacts to the failure.
Right. Basically, if the error is such that you can recover and continue, exceptions are probably not the correct answer. If the error will almost certainly result in aborting the current operation, then exceptions can be considered.
-- James Kanze mailto:ka...@gabi-soft.de Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
In article <3A361160.18BE8...@dresdner-bank.com>, James Kanze wrote: > Gabriel Zachmann wrote:
[snippage]
> > c) should exceptions be used only for "exceptional" cases, or > > could they also be used for not-so-exceptional things, like > > bogus parameters passed in from the caller?
> I would hope that a bogus parameter is something really exceptional, > if it comes from within my program. I wouldn't use exceptions for > errors in user input, however.
I would say that a bogus parameter is probably too exceptional to handled by an exception.
The problem with throwing an exception when a programming error is detected is that at some higher level, the exception may be caught and then considered handled, while nothing has been done to fix the error that caused the exception.
Rather then letting the program muddle on, I believe it is usually better to have it log as much error information as possible and then abort, leaving it up to whatever/whoever invoked it to take appropriate action.
- Wil
-- Wil Evers, DOOSYS IT Consultants, Maarssen, Holland [Wil underscore Evers at doosys dot com]
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> [An Init method] It means that you don't have to deal with exceptions coming from that > constructor. If you defer anything that can fail to a later > initialize function, you can handle a return code.
But I wouldn't regard this as an advantage, as I believe failures should be handled via the exception mechanism.
> If you use a > factory, you can delete the object if the initialization fails, and > return a null pointer.
If the failure comes from the constructor, there is no need to delete the object, of course.
> If on the other hand, you use an internal > failure flag, like iostream, you can integrate the error handling into > that of the normal case, again like iostream.
True...that's never especially appealed to me, though.
> Globally, making it an absolute rule not to throw from a constructor > only makes sense (to me) if you are designing to not use exceptions > anywhere.
Agreed.
But even in constructors, exceptions should only be used
> for exceptional cases, so you will occasionally have cases where other > mechanisms are needed anyway.
Guess I'd have to see a specific case.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
> In article <3A361160.18BE8...@dresdner-bank.com>, James Kanze wrote:
> Rather then letting the program muddle on, I believe it is usually > better to have it log as much error information as possible and then > abort, leaving it up to whatever/whoever invoked it to take > appropriate action.
Repeat after me: It all depends on the program.
Every program will have different costs and benefits of "muddling on". If the cost is low enough (the program can't do much harm--it's not guiding missiles or anything) and/or the benefit is high enough (by not aborting, you at least give the user the chance to save her work), then muddling on is appropriate.
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]
James Kanze <James.Ka...@dresdner-bank.com> writes: >exceptions should only be used for exceptional cases
This is a commonly-repeated (I used to say it too) but fuzzy statement. Its main problem, borne out in many newsgroup discussions, is that what's "truly exceptional" is subjective and hasn't so far been a reliable guide. Some think it means hard errors where the system is going to crash anyway. Others think it also includes serious errors where a major operation can't be completed. Still others think it means when any operation, large or small, can't be completed. A few people would even include "success with info" warnings, meaning anything beyond "OK, done" would be an exception -- to them, anything short of clear success is to them an "exceptional case."
So my question is: What does "exceptional cases" mean to you? Can you give a clear and rigorous definition that can be used to make decisions about new cases? If so, I can take the definition and apply it to some cases and see whether or not I agree with it -- and, more importantly, why or why not. Again, in fairness, I used to say the same thing, and after a several muddled attempts over time I realized I was guilty of fuzzy thinking because I couldn't decide on a clear and unambiguous definition.
I've finally come around to Dave Abrahams' view:
Exceptions are basically just glorified return codes with different semantics,
the main semantic differences being that exceptions: a) can't be ignored; b) don't have to be manually propagated up to a suitable handler; and c) require some more care in intermediate code so that stack unwinding is safe. The first two are clear advantages; the last is now (finally) well-understood but does require extra coding discipline and will continue to be a source of articles and talks and maybe even some new analysis about cases not yet discovered/covered (although it's widely believed that the area is indeed now sufficiently well covered to declare it "well-understood" as I just did).
Let me float an idea and see what comes out: A lot of people lump the choice of exceptions vs. return codes into the error handling strategy, but I think it's useful to distinguish between the mechanism and the strategy. That is, choices about error handling strategy (what errors to detect/report, and what/where to correct them) could be orthogonal to the reporting method (the middle piece, what mechanism to use to report them); together, both would form the error handling policy. Comments? Reactions?
> Then have an Init() function that does the actual initialization.
> You asked.
> It buys a big plus in some situations, delayed activation...
But this idiom introduces a completely new kind of error -- attempts to access an uninitialized object. Does every member function test to make sure the object has been initialized? That's a lot of clutter in the code. Or do you just allow the use of uninitialized objects to eventually cause a crash?
[ Send an empty e-mail to c++-h...@netlab.cs.rpi.edu for info ] [ about comp.lang.c++.moderated. First time posters: do this! ]