From: ThosRTanner on 11 Feb 2010 02:06 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: > > > That function *might* throw because the constructor for > > std::vector<int> isn't declared throw(). > > > A function won't throw if and only if the only functions it calls > > doesn't throw (and it doesn't throw itself of course). What you can > > never tell is if it it will throw but I don't think that's important. > > > 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. > For instance, how can you tell if the function qsort throws? You have > to analyze the compare function, which might be determined at run time. > Worse, what happens if that compare function calls a global function > stored in a tr1::function? The qsort function can't throw because it is a C function, and anything you pass to it should be an extern "C" function and extern "C" functions can't throw (because C can't cope with it) > > If the poster is really asking for a compiler extension, I'm not sure > why he is posting it here instead of asking his compiler vendor (along > with how much he is willing to contribute or pay to make it happen). Well, yes. Either that or a standards change, because if he wants all compilers to issue a diagnostic, that is a change to the standard > > Personally, I don't see much traction on this, as most folks just aren't > seeing these kinds of issues very frequently (if at all) when using > exceptions in day to day usage. > Well, in my case, as I've said before, we don't use exception specifications at all, because throwing an exception that isn't permitted by a callers exception specification causes your program to terminate, and that is not acceptable for our software. And I doubt we're the only people who have that requirement. -- [ 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 02:06 DeMarcus wrote: > > I bought the book Exceptional C++ by Herb Sutter. It's an excellent > book, buy it. However, even Sutter himself seems to be totally paralyzed > when it comes to exception specifications, as I found when I > surprisingly read the following. > > "Writing throw() limits you in the future in case you want to change the > underlying implementation to a form that could throw.", page 54. > > Now, anyone in this community, raise a hand if you would be happy if one > of your programmers or colleagues suddenly started to throw from a > no-throw function. It's a silent and efficient way to put a company in > Chapter 11. Only if you relied on the fact that the function did not throw. And you don't usually want to do that except for a few specific functions advertised and well-known as non-throwing, such as destructors, pop_back(), erase(), swap(), and so on. And some of them (especially templates) depend on other functions not throwing, so throw() can not be applied uniformly. So, the general rule is to assume that most functions can throw, and program defensively. Fortunately, with proper techniques such as RAII, the additional burden can be made minimal. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Andreas Wallner on 11 Feb 2010 02:15 A few posts ago you described how you would use your proposed warning for your own code. You would have to sort out a huge mass of warnings related to librarys using exception specifications. You could not run those compilations as part of a regression test. I think that you would most likely overlook some issues although you checked for issued, just because of the huge amount of repetitive work the programmer checking the compiler output would have to do. >void f() throw() >{ > try { myVector.pop_back(); } catch(...) {} >} That could for, but what if you accidentially wrap something in such a try-catch block that is not-nothrow? I would consider it really bad if that happened... Also I wouldn't use throw() because of the additional code that is generated and does not help me in any way. >That is why I proposed it as an optional feature so that it won't affect >nobody except those who see it as a help. As for me, until this no-throw >issue has gotten a clean solution, I prefer this clutter code to a core >dump. If you are sure that the function you wrapped with your try-catch block is really nothrow, you would never have to fear a core dump. If you are not sure that the function is nothrow then you would swallow the thrown exception, and have ignored it... I would feel better with an application that catches this exception at an much higher level, then just swallow the exception and never have a clue that it was thrown. I think such a warning would introduce more problems then it would solve. You would write code that has no functional use, that is only there to be able to do checks with that specific compiler warning (you would anyway have to check by hand). >Now, anyone in this community, raise a hand if you would be happy if one >of your programmers or colleagues suddenly started to throw from a >no-throw function. It's a silent and efficient way to put a company in >Chapter 11. It would be better to say that you should only use throw() (if you use it at all) if you had to, but not if you could (depending on the current implementation). I think that solid test cases for your own stuff, as well as code reviews would be a better approach to this problem. Or try to write a static code analysis tool that can do this, like some others already suggested. But without parsing library code as well such a tool might not be usable at all. (Because of the above mentioned problems) -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Goran on 11 Feb 2010 02:14 On Feb 11, 2:17 am, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote: > "Writing throw() limits you in the future in case you want to change the > underlying implementation to a form that could throw.", page 54. > > Now, anyone in this community, raise a hand if you would be happy if one > of your programmers or colleagues suddenly started to throw from a > no-throw function. It's a silent and efficient way to put a company in > Chapter 11. 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. So your argument is a poor way to turn things around. Because, with throw(), if thing throws, you die. Without throw() (and surrounding code is not exception-safe), you have a serious bug. Either way, you have a bug. But former case, with throw(), is actually much more drastic - you die right away. So if absence of throw() in an otherwise no-throw function puts company in Chapter 11, then it's presence can only put it there faster. Goran. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Jeff Schwab on 11 Feb 2010 02:15
Francis Glassborow wrote: > DeMarcus wrote: >>> >>> And part ofg that mechanism will have to be a way to reassure the >>> compiler that a function call will not throw (or to put it another way, >>> if it does then the programmer takes full responsibility) >>> >>> Just for the purposes of exposition: >>> >>> int foo(int); // programmer has not declared foo >>> // not to throw >>> >>> int bar() nothrow { >>> int i(nothrow foo(0)); // assures compiler that >>> // this call will not thorw >>> // more code >>> } >>> >>> I think that some such mechanism is necessary to deal with the many >>> existing libraries where perfectly reasonable functions that will not >>> throw have not been declared as not throwing. >>> >>> >> >> Yes, you're right, but to make it simple, i.e. keep the fingers away >> from the standard, we can solve it like this for now. >> >> int foo(int); // programmer has not declared foo >> // not to throw >> >> int bar() throw() { >> try { >> int i(foo(0)); >> } >> catch(...) {} // assures compiler that >> // this call will not thorw >> // more code >> } > > But that is exactly the kind of added complexity that I do not want to > clutter my code with. It shouldn't be hard to wrap in a library, especially with the new support for type inference. namespace { template<typename F> class nothrow { F m_f; public: typedef typename F::argument_type argument_type; typedef typename F::result_type result_type; nothrow( F const& f ) : m_f( f ) { } result_type operator()(argument_type const& a) throw() try { return m_f(a); } catch (...) { return result_type( ); } }; template<typename F> nothrow<F> make_nothrow(F const& f) { return nothrow<F>( f ); } int foo(int) { throw 42; } } #include <functional> #include <iostream> int main() { try { std::clog << "foo returned " << foo(42) << '\n'; } catch (...) { std::clog << "foo threw\n"; } auto bar = make_nothrow(std::ptr_fun(foo)); std::clog << "bar returned " << bar(42) << '\n'; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |