Prev: Deleting all panes when Miniframe is Closing
Next: How to get crash dump when a unhandled CException is thrown by a MFC app
From: Goran on 8 Jan 2010 15:09 On Jan 8, 4:37 pm, Peter Schneider <peter.m.schnei...(a)gmx.de> wrote: > On 7 Jan., 15:32, Goran <goran.pu...(a)gmail.com> wrote: > > > In particular, though, I do think that CInvalidArgException is bad, > > because it's usually a sign of a bug in the program. But exceptions > > are strictly __NOT__ a mean to treat bugs, not in the slightest. On > > top of that, there's this unlucky change in behavior between MFC > > versions (bad index would essentially crash before, but will throw > > now). > > If I remember correctly, Java uses exceptions for both "normal" error > handling and for reporting programming errors including assertions. > And that seemed to work pretty well and has the advantage that there > is only one mechanism used. > > Contrast this to C++ and in particular to C++ on WIN32 where there are > many different handlers for all kinds of unexpected errors (e.g. > _set_abort_behavior, _set_purecall_handler, > set_terminate,set_unexpected, SetUnhandledExceptionFilter, ...) > > So where do you see the general problem with using exceptions to > report programming errors? > And how do you think programming errors should be reported in C++? Clear-cut theoretical answer, for me, is: code that errs should crash, preferably with a crash dump and as soon as possible. That's invaluable for the ease of development, because that helps the most in finding the source of the problem. Of course, in practice, things get muddy. Often, once error is detected, it's already too late (e.g. stranded pointer). OTOH, with that drastic approach, "user experience" suffers. I'd guess that numerous coders have been forced by their respective marketing or whatever departments to try to continue running even though there's something horribly wrong, and frankly, I can see that point, too. I personally would not touch most of functions you list there - problems that cause them to be invoked are way too bad for me to try to get smart. So quick death there, using the default behavior. (Luckily, I don't remember when was the last time I got pure e.g. virtual call error). I do use SetUnhandledExceptionFilter to produce crash dump, though (but I TerminateProcess immediately after that). WRT Java situation - I am ambivalent WRT benefits in mixing exceptions caused by bugs and "legitimate" exceptions (ones caused not but bugs but rather by "unusual" conditions). I think that such environments continue even in case of an error-exception is more consequence of general programming model where all throws, than a conscious decision to do so. Goran.
From: Goran on 8 Jan 2010 15:31 On Jan 8, 5:40 pm, Joseph M. Newcomer <newco...(a)flounder.com> wrote: > If you throw an exception that is not CException-derived, then you bypass the MFC handler. Yes. I think, ideally, an MFC program should abstain from throwing anything else. (Or, if anything else is possible, it's an error). In fact, in general, a given piece of C++ code should only have one base exception class. That's because one does not want catch(type1) {} catch (unrelatedType2) all over the place, nor does one want to think about different exception types all the time. That's one thing e.g. Java gets better It just mandates Throwable, easy. But I had one situation in C++, where I much enjoyed freedom to define my very own base exception class not oming from either MFC, ATL or STL. Luckily, one-base-exception-class is already the case, or achievable, in MFC code. For example, AFAIK, any exception coming from standard library is a genuine bug, so it should not happen and does not count. Exceptions from compiler COM support can be "converted" to MFC-based exception through a callback hook (I can dig it out, but can't remember it now). Exceptions of third-party libraries can either provide similar hook, or be calls to them wrapped and exceptions rethrown as MFC exceptions. IOW, life in C++ land is full of freedom, but hard... > I never understood why it ever made sense for the MFC dispatch loop to catch any > CException; as pointed out, the program is in an ill-defined state. No, ill-defined state is far from a general case. Look: BYTE b[10]; CFile(path, mode).Read(b, 10); Here, all sorts of things that can go wrong, and will be signaled through an exception. But there's no ill-defined state to be had. IOW, when exceptions are used as control flow mechanism in face of unexpected and/or rare conditions, all is fine. But when exceptions signal code errors, it's bad. If that's the case, exception can even do more harm than good (heck, like in this post). That's why I wrote up there that exceptions are strictly __not__ bug-handling tool. Goran.
From: Giovanni Dicanio on 9 Jan 2010 12:31 "Goran" <goran.pusic(a)gmail.com> ha scritto nel messaggio news:5a154bf2-ea77-49dc-a680-fa7acdb3f458(a)s31g2000yqs.googlegroups.com... > Luckily, one-base-exception-class is already the case, or achievable, > in MFC code. For example, AFAIK, any exception coming from standard > library is a genuine bug, so it should not happen and does not count. Goran: could you please clarify this? The standard library can throw std::bad_alloc in case of allocation failure, and I think that is not a "genuine bug"... (I would categorize an allocation error as a form of error condition.) Or probably I misunderstood you. Thanks, Giovanni
From: Joseph M. Newcomer on 10 Jan 2010 19:12 I do not believe it could possibly be a "genuine bug". An exception thrown by the standard library indicates an error. But the source of the error does not necessarily imply a "bug". Just looking at stdexcept, it doesn;t even mention bad_alloc as an exception; it mentions domain_error (which says it is the basis of all exceptions that report a domain error. AFAIK, this would mean something like trying to validate credentials on the wrong server...) invalid_argument Why is an "invalid argument" necessarily a "bug"? It could also be "bad input", a condition to be reported and recovered from. Note that if you EVER built any kind of input-oriented system, you realize that either you have to completely duplicate the validation of arguments that come from values the user types in, or simply pass it in blindly, catch the exception, and report to the user that their data is bad. It is NOT a "bug". length_error Could be caused by bad input. In fact, most successful attacks were caused by doing things that would be caught by out-of-range or length errors, and the correct response is not to terminate the program (only in Fantasyland is the correct solution always to terminate the program; in the real world, this is NEVER permitted! It can happen, but usually it doesn't make sense to allow it to happen!), but to report the bad data, possibly abort the current transaction, and return control cleanly to a state that allows the program to progress. logic_error See all above comments out_of_range See all above comments. Either you have to validate values, or let the library validate values. If the library throws an exception, you catch it, report the error, and go on with life. Bug? I don't think so. runtime_error Well, that's most things. Not clear how this differs from all other exception classes, since the number of compile-time exceptions is vanishingly small. underflow and overflow errors Often these are expected. Bug, no. Bad data, yes. And certain algorithms actually rely on hitting overflow or underflow to trigger certain kinds of recovery computations to ensure convergence. Building software that runs 24/7 means that NO error condition is allowed to be considered "fatal", every failure, for WHATEVER cause (bad input, program bug, who cares?) must result in a clean continuation of execution. I've built systems that recover from allocation failure, stack overflow, data overruns, etc., and it takes a LOT of work to make these do clean recovery. We had one where we did storage compaction! Try THAT in your standard C environment! [No, it is NOT fun! It required very careful programming, and essentially, all important structures were reachable from a small number of known roots, and no pointers to ANYTHING were ever retained except in the structures themselves. Our environment made it possible to discover, in these structures, where the pointers were. We probably poured 10 programmer-years into this recovery, but the program NEVER failed! Back in those days, of machines with 256K, running out of memory was a commonplace problem, and we built an entire virtual VM resembling Windows 1.0 to deal with this, ca. 1972. And the language wasn't C, but was functionally equivalent to it in all ways] By the way, building that system in 1972 led to some of the work in exceptions that appeared in our later compilers. Trying to build robust software without an exception mechanism is a losing game. joe On Sat, 9 Jan 2010 18:31:19 +0100, "Giovanni Dicanio" <giovanniDOTdicanio(a)REMOVEMEgmail.com> wrote: >"Goran" <goran.pusic(a)gmail.com> ha scritto nel messaggio >news:5a154bf2-ea77-49dc-a680-fa7acdb3f458(a)s31g2000yqs.googlegroups.com... > >> Luckily, one-base-exception-class is already the case, or achievable, >> in MFC code. For example, AFAIK, any exception coming from standard >> library is a genuine bug, so it should not happen and does not count. > >Goran: could you please clarify this? > >The standard library can throw std::bad_alloc in case of allocation failure, >and I think that is not a "genuine bug"... (I would categorize an allocation >error as a form of error condition.) > >Or probably I misunderstood you. > >Thanks, >Giovanni > > Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Goran on 11 Jan 2010 03:08 On Jan 9, 6:31 pm, "Giovanni Dicanio" <giovanniDOTdica...(a)REMOVEMEgmail.com> wrote: > "Goran" <goran.pu...(a)gmail.com> ha scritto nel messaggionews:5a154bf2-ea77-49dc-a680-fa7acdb3f458(a)s31g2000yqs.googlegroups.com... > > > Luckily, one-base-exception-class is already the case, or achievable, > > in MFC code. For example, AFAIK, any exception coming from standard > > library is a genuine bug, so it should not happen and does not count. > > Goran: could you please clarify this? > > The standard library can throw std::bad_alloc in case of allocation failure, > and I think that is not a "genuine bug"... (I would categorize an allocation > error as a form of error condition.) > > Or probably I misunderstood you. Whoops! Indeed, you are correct about bad_alloc and I didn't think that through! Can I change that to "most exceptions", pretty please? I was thinking about the likes of range_error from a vector and similar... Goran.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Deleting all panes when Miniframe is Closing Next: How to get crash dump when a unhandled CException is thrown by a MFC app |