Next: C++/CLI limitations?
From: Thiago R. Adams on 29 Jun 2005 10:50 Hi, I have a lot of questions about exceptions. In the sample below: struct E( . . . ~E(){} ); int main() { try { throw E(); } catch(const E &e) { e.some(); } } When ~E will be called? Which is the E scope? Where E will be created? In the Stack? Exceptions are slow if are not throwed? What makes exceptions slower or fast? The number of catch's influences? Using exceptions, what influences the memory? And what influences the program size? [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: tony_in_da_uk on 30 Jun 2005 07:09 Firstly, I won't answer "when ~E will be called", because a basic programming skill is putting a few cout statements in to find out for yourself. You can also work out whether E is on the stack or not, but this is a bit more difficult - the answer is yes. My recollection is that E() will be created on the normal program stack, and the catch statement may run in a dedicated exception stack (which allows exceptions to work when the main stack has been exhausted due to excessive recursion). Anyway, entering and leaving a try { } block may have overheads in many environments, but they can vary massively. Again, a basic programming skill is to benchmark things in your own environment, and/or look at the assembly output from your compiler (e.g. g++ -S). On Solaris a couple years ago, I found reporting errors via exceptions was about 15 times slower than using integral return codes (like libc), but things may well have changed. I don't recall the overhead for successful processing. Anyway, whether this is significant depends on many factors. It just confirmed my impression that the programmer I had just interviewed was being a bit silly when he insisted that he hadn't reported an error using anything other than an exception for several years. As for what influences the memory: use of exceptions may require the compiler to reserve an additional stack, but the standard C++ library uses exceptions itself, so you should have that overhead anyway. Re program size, it's just not relevant unless you're in an embedded environment, in which case I'd say again that you have to write code and make measurements with your particular compiler and processor. The general rule is use exceptions to report exceptional circumstances, not oft-encountered error conditions. Varying from this rule isn't worth doing unless you have profiling results showing you that you have to. A design example: a function written "bool is_odd(int)" probably shouldn't throw, but "void assert_odd(int)" could, because the caller is clearly saying it would be exception not to succeed. See Stroustrup's TC++PL3 for some background discussions on use of exceptions. Cheers, Tony [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Thiago R. Adams on 30 Jun 2005 13:30 Hi Tony, My question is about destructor. When it be called? Yes I made some tests with cout. I guess that the destructor is called at more external try. And the compiler is smart if you use um rethrown. But this behavior must be written is some place? or not? >You can also work out whether E is on the stack or not, but > this is a bit more difficult - the answer is yes. My recollection is > that E() will be created on the normal program stack, and the catch > statement may run in a dedicated exception stack (which allows > exceptions to work when the main stack has been exhausted due to > excessive recursion). I made some tests. I create a recusive function with try/catch and log the address of stack variables. The stack address of variables doesn't change with the exceptions. (I used visual c++ 2005 express) Then I also guess that is in other stack. > The general rule is use exceptions to report exceptional circumstances, > not oft-encountered error conditions. Varying from this rule isn't > worth doing unless you have profiling results showing you that you have > to. It's an excelent topic! :) What is one exception condition? I instead use exceptions for erros and for precoditions broken. for example: struct X{ X(AnyInterface *p) { if (p == 0) throw runtime_error("AnyInterface is obrigatory for class X!"); else p->f(); } }; I need known the exceptions overhead and behavior to convince my coworkers that is good. Today we use a lot of return codes. TC++PL3 is very good! :) I read also: CUJ august 2004, "When, for what, and how should you use exceptions" Sutter Exceptional C++ Style and C++ Coding Standard. Thank's http://paginas.terra.com.br/informatica/thiago_adams/eng/index.htm [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: David Abrahams on 30 Jun 2005 14:27 "Thiago R. Adams" <thiago.adams(a)gmail.com> writes: > Hi, > I have a lot of questions about exceptions. > > In the sample below: > > struct E( > . . . > ~E(){} > ); > > int main() > { > try { > throw E(); > } > catch(const E &e) { > e.some(); > } > } > > When ~E will be called? It depends on the implementation, because E's copy ctor may be called an arbitrary number of times, but the last E will definitely be destroyed when execution reaches the closing brace of the catch block. > Which is the E scope? I don't understand the question. > Where E will be created? In the Stack? That's entirely implementation-dependent. From an abstract point-of-view, there's "magic memory" in which all exceptions are stored during unwinding. > Exceptions are slow if are not throwed? That's also implementation dependent. On the "best" implementations, there's no speed penalty for exceptions until one is thrown. > What makes exceptions slower or fast? The number of catch's > influences? That's also implementation dependent. On the "best" implementations, there's no speed penalty for a catch block. Generally, those implementations trade speed in the case where an exception is thrown for speed in the case where no exception is thrown. In other words, on implementations I consider inferior, actually throwing an exception may be faster, but executing the code normally, when there are no exceptions, will be slower. > Using exceptions, what influences the memory? > And what influences the program size? That's also implementation dependent. There is generally no dynamic memory associated with exception-handling. As for the program size, on the "best" implementations, tables are generated that associate program counter values with the unwinding actions and catch blocks that must be executed when an exception is thrown with any of those program counter values in an active stack frame. In some implementations you can limit the number of tables generated by using the empty exception specification wherever possible. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: David Abrahams on 1 Jul 2005 05:50
"Thiago R. Adams" <thiago.adams(a)gmail.com> writes: >> The general rule is use exceptions to report exceptional circumstances, >> not oft-encountered error conditions. Varying from this rule isn't >> worth doing unless you have profiling results showing you that you have >> to. > It's an excelent topic! :) What is one exception condition? > I instead use exceptions for erros and for precoditions broken. Broken preconditions should almost always be handled with an assert and not an exception. An exception will usually cause a great deal of code to be executed before you get a chance to diagnose the problem. -- Dave Abrahams Boost Consulting www.boost-consulting.com [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |