Prev: Can there be parallel initialization of global variables in C++0x?
Next: Container adapter to treat a sorted vector as a set
From: wij on 2 Jun 2010 22:30 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 2 Jun 2010 22:34 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 3 Jun 2010 04:38 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 3 Jun 2010 04:39 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 3 Jun 2010 04:54 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! ]
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Can there be parallel initialization of global variables in C++0x? Next: Container adapter to treat a sorted vector as a set |