6 ms·
It should be well-known that actually throwing an exception in C++ is extremely costly. I think it is also fairly widespread knowledge that even allowing the c
by thedance 7y ago
It should be well-known that actually throwing an exception in C++ is extremely costly. I think it is also fairly widespread knowledge that even allowing the compiler to support exceptions has runtime costs. Exceptions do not conform to C++'s "zero-overhead" principle. That's why numerous large organizations from NASA to the Dept. of Defense to Google decree that C++ exceptions must not be used.
- dana321 7y agoIts unrolling the stack, whatever could go wrong?.. Its only expensive when you throw an exception. They should only be used in exceptional circumstances, but they appear to be littered among libraries for everything from telling the caller that the end of file has occurred to a connection timing out.
- thedance 7y agoThe cost comes from having to track what automatic and temporary objects have been created and attaching them to the exception context so you can destroy them if an exception is thrown. Another cost is having to track which base classes of a derived class have already been constructed when the derived constructor throws. You get noticeably better generated code when the compiler can skip all that junk.
- AnimalMuppet 7y agoWait a minute. > The cost comes from having to track what automatic and temporary objects have been created and attaching them to the exception context so you can destroy them if an exception is thrown. Doesn't it have to do that anyway, in case you return from a function, or break from inside a loop? Anytime you can leave a scope, it has to be able to do that. > Another cost is having to track which base classes of a derived class have already been constructed when the derived constructor throws. All of them have been constructed before you begin the derived constructor.
- thedance 7y agoThanks for holding the discussion to exact standards. What I meant about the base class constructors is the compiler must generate a derived-class constructor that can unwind the completely constructed base in case the derived class throws, not to mention the ability to destroy constructed subobjects with non-trivial destructors in case one of _their_ constructors throws. When your project decides to outlaw exceptions then none of these events are even possible and the compiler will generate a much more compact and infallible constructor. As for leaving the scope, you're right again and I was unclear. The problem is you are destroying automatic objects while returning from a scope and one of them throws. Now you have extra code and extra branches for all of that. The extra ways of exiting a scope generally bloat up the program, and the size and complexity of a function can prevent it from being inlined or otherwise optimized by the compiler. These are systemic performance concerns that won't just show up as hot spots on a profile.
- AnimalMuppet 7y agoAh, yes, I wasn't thinking about throws during destructors. IIRC, that's considered bad form but not forbidden, and so a compiler would have to handle that. (Feel free to correct if I have that wrong.) As to your first paragraph: That's just calling the base class's destructor if the derived class's constructor throws. That's easy - that's what the base class's destructor is for. It's essentially one function call. The harder part (or so it seems to me) is correctly destroying the only-partially-constructed derived class.
- ncmncm 7y agoThe compiler has to handle it, but the Standard Library definitively doesn't.
- daemin 7y agoThrowing during destructors will generally result in a std::terminate, since you have good odds of throwing during destruction of an object that is being cleaned up as a result of an existing in progress exception. So it is not forbidden but odds are you'll have your program terminate.
- UncleMeat 7y agoThe compiler has to generate code that works when exceptions are thrown. This limits some optimizations and adds overhead even if nothing happens at runtime.
- TeMPOraL 7y agoI don't recall NASA outright banning C++ exceptions - especially not organization-wide. Code running on space hardware has very specific risk profile, and AFAIK NASA dislikes exceptions there because they add risk to code (without a mechanism like Java's checked exceptions it's too easy to add a code path that can generate an unhandled exception, terminating the program).
- thedance 7y agoI'm sure it varies from one group to the other. This CppCon talk from 2014 says no exceptions are permitted in mars rover flight software. https://github.com/CppCon/CppCon2014/blob/master/Presentations/C%2B%2B%20on%20Mars%20-%20Incorporating%20C%2B%2B%20into%20Mars%20Rover%20Flight%20Software/C%2B%2B%20On%20Mars%20-%20Mark%20Maimone%20-%20CppCon%202014.pdf https://github.com/CppCon/CppCon2014/blob/master/Presentatio...
- TeMPOraL 7y agoYeah, but the slides don't give a reason why; the only hint is a prior slide mentioning the "historic arguments against using C++ in flight", namely "Exceptions: too much uncertainty, difficult to validate all possible control paths". And that has nothing to do with performance.
- klingonopera 7y agoZeroMQ's author has written a wonderful article about how he should've picked C in place of C++ in a mission-critical setting, even despite personally preferring C++ himself. http://250bpm.com/blog:4 http://250bpm.com/blog:4
- boring_twenties 7y agoNot using them is insufficient, they should be disabled at compile time. IMHO, of course.
- kevin_thibedeau 7y agoNow what happens when new or STL throws something?
- thedance 7y agoWhen you disable exceptions anything that throws calls std::terminate instead. It's actually great.
- pansa2 7y agoIs this automatic, or do you need to set it up somehow? `set_new_handler`?
- thedance 7y agoThe standard doesn't give advice about how to break features of the standard, so disabling exceptions is a non-standard feature of the implementation. If you're planning to disable exceptions you'd better read the docs that come with your compiler.
- cmrdporcupine 7y agoI believe the exception ban at Google these days is justified more on the grounds that integrating with existing code would be problematic, rather than on performance grounds. I seem to remember reading something to that effect.
- billti 7y agoTheir coding guidelines on the topic lay out the pros/cons and ultimate reasoning pretty well: https://google.github.io/styleguide/cppguide.html#Exceptions https://google.github.io/styleguide/cppguide.html#Exceptions
- thedance 7y agoThat may be the explanation they've settled on but there are build artifacts at that company which would be impossible to link without -fno-exceptions, so there are also practical problems.
- ncmncm 7y agoThis is correct. Google have many, many million lines of casually exception-unsafe code they cannot afford to fix, so any rationalization is only that. The choice is off the table.
- quietbritishjim 7y agoA couple of misconceptions here: > It should be well-known that actually throwing an exception in C++ is extremely costly. Unfortunately it is well known, but without really understanding what "extremely costly" means. The article shows it is expensive compared to returning from a function that does almost nothing. But what about compared to allocating some memory? Or locking a mutex? Just recently here on Hacker News I recently saw someone worryung about using an exception to close a file after doing a bunch of reads because they thought it would be too slow – but, in reality, the time taken to read a whole file is astronomical compared to throwing an exception. > C++'s "zero-overhead" principle Now it's possible you're right here, but just to be clear: this principle just means features don't have a cost if you don't use them. For example, if you don't need a function to be virtual then you don't have to mark it as such, so the fact that C++ supports virtual methods didn't cost you anything. But if you do choose to mark a method as virtual then there will be costs involved (memory will be taken up with the vtable and pointers to it, invocations through a pointer will take longer). Similarly, the fact that throwing exceptions isn't zero cost does not violate this principle. The reason I say you could still be right is that there is still a memory cost to including tables of unwinding information for exceptions even if you never throw them. Perhaps that's what you meant, but the surrounding text seems to be hinting at the cost of throwing them.
- thedance 7y agoExceptions being contrary to zero-overhead is not something that is just my opinion. Here's Herb Sutter's detailed white paper on the topic: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r1.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p070... ETA: an uncontended mutex lock takes around 10-30ns depending on the machine. Any kind of exception is far more costly.
- qeqeqeqe 7y agoBjarne Stroustrup wrote a rebuttal to that proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1947r0.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p194...
- qeqeqeqe 7y agoI suggest that people read Bjarne Stroustrup's recent paper on why exceptions are necessary to see the counter point http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1947r0.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p194...
- gumby 7y ago> Exceptions do not conform to C++'s "zero-overhead" principle. That's why numerous large organizations from NASA to the Dept. of Defense to Google decree that C++ exceptions must not be used. I don't know about NASA's case, but Google's style guide forbids exceptions only for legacy reasons. In fact it praises them: "On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dependent code. ... Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions." Since I'm not working on Google's old code base I do use exceptions.
- toolslive 7y agoIt's even so well known that this infects thinking about exceptions in other languages. However, there are languages where throwing of an exception is as cheap as any other function call (fe when they are compiled via the so called "double barrelled continuation style" strategy)