Live data from Hacker News

Real cost of C++ exception vs error-code checking

lazarenko.me

41–50 of 64 posts

Re: Real cost of C++ exception vs error-code checking

#41
post #12
post #8

Earlier quoted context omitted.

Cache sizes have not seen gains proportional to RAM or HDs.

Sure they have. My 486 built in 1993 had 8 KB cache, 4 MB RAM, and a 120 MB HD. My desktop built in 2009 has 2 MB cache, 2 GB RAM, and a 250 GB HD. Okay, the cache has lagged behind by one or three doublings compared to the other storage types. But that's still pretty close to proportional in a world of exponential gains.

> My 486 built in 1993 had 8 KB cache, > My desktop built in 2009 has 2 MB cache

That "2 MB" is either L2 or L3, which your 486 didn't have.

The L1 on your desktop is not much larger than the only cache that your 486 had.

As frequency increases, the length of the path that a signal can travel in one clock decreases. Fortunately, cycle-time increases have been accompanied by transistor size decreases, so the net result is that L1 sizes have been roughly constant.

Re: Real cost of C++ exception vs error-code checking

#42
post #12
post #8

Earlier quoted context omitted.

Cache sizes have not seen gains proportional to RAM or HDs.

Sure they have. My 486 built in 1993 had 8 KB cache, 4 MB RAM, and a 120 MB HD. My desktop built in 2009 has 2 MB cache, 2 GB RAM, and a 250 GB HD. Okay, the cache has lagged behind by one or three doublings compared to the other storage types. But that's still pretty close to proportional in a world of exponential gains.

You're comparing L1 cache with L2 cache. Even a modern CPU like the Core 2 Duo only has about 32 KB of L1 cache per core.

Re: Real cost of C++ exception vs error-code checking

#43
post #40

Earlier quoted context omitted.

You can accomplish this by using asserts in your code. You don't need exceptions to get a callstack and you can assert that values are valid and force a crash / callstack dump when they're not. On top of that, you can compile the asserts out for release builds if you're confident they won't be hit.

Normally you turn assert() off for production buids, so it's not a robust solution, as some error conditions may not get generated in testing. The memory protection catches a lot of out-of-bounds memory references pretty well, and if you enable core dumps, you can extract neat backtrace from the core file (provided your routines fail-forward in case of invalid arguments). Moreover, some compilers can be instructed to…

And if you are worried about vendor lock-in, you can hide it behind a #define

Re: Real cost of C++ exception vs error-code checking

#44

Nice article but as far as I'm concerned you don't need to _prove_ this as it is a logical fallacy to start with. If an exception is being thrown then something is wrong, if something isn't wrong then you implemented your exceptions incorrectly as exceptions shouldn't exist in normal program flow. So to recap, you're writing a crap ton of more code just so you can return your error code _slightly_ faster than it woul…

I think you partially missed the point - it's not that throwing exceptions is slow, is that even having them in your code is [allegedly] slow.

According to the article there are two methods used to implement exceptions in C++ - one that has higher overhead when you throw an exception (zero-cost) and one that has higher overhead when you call a function that might throw an exception (setjmp/longjmp).

Unfortunately the author didn't go over the latter method, which would have been more interesting.

Re: Real cost of C++ exception vs error-code checking

#45
post #2

I prefer Raymond Chen's take on exceptions: http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/35294...

"since you have to check every single line of code (indeed, every sub-expression) and think about what exceptions it might raise and how your code will react to it" Yes, that's my concern with exceptions as well. It seems like the Java model (if I remember it right -- it's been a decade), which requires a method to either handle an exception that a sub-method throws or explicitly allow it to be thrown, would be prefe…

Requiring all exceptions to be checked is evil. It leads to horrendous abstraction leakage (I need to let every caller know I use FooBarWidget in the core of my application??), improper error handling (just catch whatever comes out and move on so I don't have to declare it), or ubiquitous error wrapping (every class has a try...catch that turns the called exceptions into new exception types to throw).

Ironic that C++ is moving towards that as the Java community is moving away (by relying more on RuntimeException, which isn't checked).

Re: Real cost of C++ exception vs error-code checking

#46
post #15
post #4

Earlier quoted context omitted.

I didn't see any timings in his code.

Yes. How can he possibly say that "exceptions are faster" without such timings? C++ style, unwind-the-stack-and-call-destructor exceptions must really have a high run-time cost when an exception occurs. Also, his instruction count misses the instructions that occur at run-time handling an exception. Even when an exception doesn't occur, it isn't obvious that some run-time code doesn't get excuted.

But you have to unwind the stack either way. With exceptions, the exception handling does it. With error checking, you do it every time you type "if (something() == -1) return -1;"

Re: Real cost of C++ exception vs error-code checking

#47
Perhaps the worst problem with checking-vs-exceptions is, either solution dominates your code structure, obscuring the algorithm logic.

The holy grail would be some method of ensuring the code cannot fail e.g. weirdly constrained argument semantics. Thus separating algorithm from constraints instead of shuffling them together on the page like a deck of cards.

Re: Real cost of C++ exception vs error-code checking

#48
post #37

Earlier quoted context omitted.

Hmm, well, I'm relatively young so I guess I missed all those broken promises :P Still, I think the "trying to code like C in C++" point still stands.

A compressed version can be obtained simply by comparing the initial release of C++ to modern C++, and recalling that the initial version of C++ itself shipped with, well, pretty much the same set of promises that modern C++ ships with.

I think you could replace C++ with many, many things involving computers in that sentence.

Re: Real cost of C++ exception vs error-code checking

#49
post #2

I prefer Raymond Chen's take on exceptions: http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/35294...

This reads to me like 'writing good code is hard, and writing even better code is even harder'. With modern C++0x smart pointers (like unique_ptr) and RAII, you can get very high performance and (more) easily exception-safe code. Maybe a lot of C++ exception criticism comes from people still trying to code like C in C++?

But your exception-safe C++ code soon becomes bloated with shared_ptr and unique_ptr templates and copy ctors. Almost any C++ function, overloaded operator, or some implicit temporary object's ctor can throw an exception without warning. You must use RAII everywhere for every "resource".

Exception-safe RAII is pretty much an all-or-nothing affair.

Re: Real cost of C++ exception vs error-code checking

#50
post #27

Today with terabyte harddrives, gigabytes of RAM and broadband connections, when is the binary size a more important factor than both execution speed and ease of development? Especially when the binary size difference is probably not huge? Shouldn't the advice of this article just be "use exceptions"?

Symbian uses their own kind-of-exceptions (called TRAP, I think) and I've heard that decision to not use C++ exception was funded on binary size constraints.

Symbian LEAVEs and TRAPs predate C++ exceptions. Symbian/EPOC is old! :)
Post reply on HN