From: Seungbeom Kim on 11 Feb 2010 14:34 Goran wrote: > > I think that you misunderstood this, and I think that's because you > fail (or refuse?) to accept what throw() does. By writing throw(), I > am NOT saying "this does not throw". I am saying "if this throws, I > die". That's a BIG difference. But from the caller's perspective, they are equivalent because the caller doesn't notice a thrown exception. Dying rather than actually throwing an exception is a way for the callee to meet the requirement/contract that it will not throw. On the other hand, "this returns normally without throwing" is certainly different from "if this throws, I die", because the former doesn't allow not returning whereas the latter does. So we have many ways to "finish" a function: (a) to return normally (without throwing) (b) to throw an exception (c) to terminate the program (by exit, abort, or exec family) (d) to keep going without ever finishing (e.g. by an infinite loop) and throw() guarantees only that (b) will not happen. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nevin :-] Liber on 11 Feb 2010 14:34 In article <4b748f32$0$283$14726298(a)news.sunsite.dk>, DeMarcus <use_my_alias_here(a)hotmail.com> wrote: > Today this > no-throw issue is a problem for at least three reasons. > > * It's stressful to do a thorough no-throw investigation since the > compiler won't help you. > * It's way too easy to accidentally throw from a no-throw function > without any warning from the compiler. > * Since the compiler doesn't warn you, design flaws can easy slip > through and survive until a refactoring would cost as much as rewriting > the whole application. You say that, but you don't mention any projects where these problems indeed show up. What open source projects, for instance, suffer from these issues? If these are real, practical problems, I'd like to see the code to try and understand why people are having these issues, because I just don't see them. Your experience doesn't seem to match mine. Again, I'm not looking for contrived, theoretical problems, but issues people are having today in real code. -- Nevin ":-)" Liber <mailto:nevin(a)eviloverlord.com> 773 961-1620 [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Seungbeom Kim on 11 Feb 2010 14:34 ThosRTanner wrote: > On Feb 11, 1:16 am, "Nevin :-] Liber" <ne...(a)eviloverlord.com> wrote: >> In article >> <82be602f-bb4e-45af-a04e-fcbeee7fd...(a)z17g2000yqh.googlegroups.com>, >> ThosRTanner <ttann...(a)bloomberg.net> wrote: >>> It is trivially easy to statically analyse whether or not a function >>> might throw. You can even tell precisely what it might throw. >> Not without whole program analysis. > > No. It is trivial. What a function can throw is the union of the > exception specifications of all the functions it calls, and all the > throws it executes. A function without an exception specification can > throw anything. An extern "C" function should throw nothing as it > breaks the contract of being callable by C if it does that. Then it quickly becomes useless because you assume a called function can throw anything and all you can assert about the calling function is that it can throw anything. Especially with templates or functors. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: ThosRTanner on 12 Feb 2010 05:39 On Feb 12, 7:34 am, Seungbeom Kim <musip...(a)bawi.org> wrote: > ThosRTanner wrote: > > On Feb 11, 1:16 am, "Nevin :-] Liber" <ne...(a)eviloverlord.com> wrote: > >> In article > >> <82be602f-bb4e-45af-a04e-fcbeee7fd...(a)z17g2000yqh.googlegroups.com>, > >> ThosRTanner <ttann...(a)bloomberg.net> wrote: > >>> It is trivially easy to statically analyse whether or not a function > >>> might throw. You can even tell precisely what it might throw. > >> Not without whole program analysis. > > > No. It is trivial. What a function can throw is the union of the > > exception specifications of all the functions it calls, and all the > > throws it executes. A function without an exception specification can > > throw anything. An extern "C" function should throw nothing as it > > breaks the contract of being callable by C if it does that. > > Then it quickly becomes useless because you assume a called function > can throw anything and all you can assert about the calling function > is that it can throw anything. Especially with templates or functors. > The same would be true for const if it was runtime checked. It's easy to do static checking of throw specifications at compile time because the compiler knows the throw spec of all the called functions, because it has to see the prototype before it can compile the call. Now, whether or not it is helpful for no throw spec to mean the function can throw anything is another question entirely. It's not useless - you just have to tighten your throw specs up from the bottom upwards. However, I know that this: void randomfunc(): void fred() throw() { randomfunc(); } can potentially crash. So I can't use it. It's no use saying "I know that randomfunc() doesn't throw", because someone might change randomfunc(). There's nothing in the compiler that'll stop them doing it. And my program will terminate unexpectedly. And that is entirely useless. If the compiler error'd that sort of thing, I'd be unbelievably happy, because throw specs would be of some use, rather than adding a whole load of code to the executable with the express purpose of terminating my program because I'd broken the interface guarantee made by the prototype. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Goran on 12 Feb 2010 05:42
On Feb 12, 8:34 am, Seungbeom Kim <musip...(a)bawi.org> wrote: > Goran wrote: > > > I think that you misunderstood this, and I think that's because you > > fail (or refuse?) to accept what throw() does. By writing throw(), I > > am NOT saying "this does not throw". I am saying "if this throws, I > > die". That's a BIG difference. > > But from the caller's perspective, they are equivalent because the caller > doesn't notice a thrown exception. Dying rather than actually throwing > an exception is a way for the callee to meet the requirement/contract > that it will not throw. Yes, but the target of throw() is bigger than any particular caller: if it fires e.g. unexpected(), something is so seriously wrong with the program that any particular caller is irrelevant. > On the other hand, "this returns normally without throwing" is certainly > different from "if this throws, I die", because the former doesn't allow > not returning whereas the latter does. > > So we have many ways to "finish" a function: > > (a) to return normally (without throwing) > (b) to throw an exception > (c) to terminate the program (by exit, abort, or exec family) > (d) to keep going without ever finishing (e.g. by an infinite loop) > > and throw() guarantees only that (b) will not happen. I think that you just perverted the course of justice ;-). What I wrote up there is (what I think is) the purpose of throw(): it's merely a way to specify that an exception from a particular function is so unexpected that program should die. Of course, standard offers options, but if you go with a, d, you are perverting throw(); options should only be used to... ahem... "enhance" on default behavior, not significantly change it. IOW, a and d are a case of "just because you can, doesn't mean you should". Goran. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |