Live data from Hacker News

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

lazarenko.me

21–30 of 64 posts

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

#21
I assume he was proving a point where main() of his full program using error code checking was not in fact checking the return value of foo()

Even in simple example code like this you can forget a check. In this case that result would be undefined if any call to devide failed.

I'd much rather have my program blow up with a readable stack trace pointing to where it happened than it working with a basically random value and then maybe blowing up somewhere totally unrelated or worse, destroying user data.

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

#22

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…

It's not slightly faster, it can be an order of magnitude faster. Example: a listen loop which handles disconnections through exceptions. This isn't stupid but it's not very efficient.

Why is it not stupid? If disconnections are part of normal application flow then why would you use an exception?

You are correct, I was somewhat disingenuous with _slightly_ faster. It is lots faster but lots faster in error cases, which from a philosophical angle is still absurd.

As long as you use your exceptions for "bad shit" (uncommon error conditions or completely unexpected failures or returns) then I still strongly believe that the performance comparison is silly.

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

#23

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…

It's not slightly faster, it can be an order of magnitude faster. Example: a listen loop which handles disconnections through exceptions. This isn't stupid but it's not very efficient.

Maybe I'm missing something. Are you saying that in your application, handling rarely-occuring unanticipated disconnections via exceptions has such high overhead that its results in unacceptable performance?

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

#24

Earlier quoted context omitted.

You're thinking of "checked exceptions" and C++ already has them (pre 0X) via the "throws" clause on method declarations. Checked exceptions is a hotly debatted topic and I think the world has kinda finally come around to deciding that the are a bad idea overall. Google it and see for yourself.

I don't know that it's accurate to compare C++ exception specifications with Java-style checked exceptions. Exception specifications aren't checked at compile time and typically don't do what you want at runtime.

shrug You're probably right. I've never really used them in C++, especially because I tend to avoid C++ in favor of the smallest possible amount of C to bootstrap primary use of a much higher level language.

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

#25
post #21

I assume he was proving a point where main() of his full program using error code checking was not in fact checking the return value of foo() Even in simple example code like this you can forget a check. In this case that result would be undefined if any call to devide failed. I'd much rather have my program blow up with a readable stack trace pointing to where it happened than it working with a basically random valu…

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.

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

#26
post #13

Earlier quoted context omitted.

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++?

"modern C++" has changed meanings so many times in the past 10 years that it's not funny anymore. there's always some "modern" solution in C++ that ends up causing more problems, leading to further "modern" solutions that end up... you get my point. some folks have decided to get off the C++ feature treadmill and go back to, well... getting things done with solid languages (e.g. C) instead of learning about the lates…

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.

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

#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.

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

#28
post #21

I assume he was proving a point where main() of his full program using error code checking was not in fact checking the return value of foo() Even in simple example code like this you can forget a check. In this case that result would be undefined if any call to devide failed. I'd much rather have my program blow up with a readable stack trace pointing to where it happened than it working with a basically random valu…

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.

Sure I can use asserts. But I'm as likely to forget the assert() as I am to forget to check the return value.

And even if I did: If you consider the faulty main() in the linked article: How would you use assert() there to make sure that result as used after the call to foo() is actually usable? If foo() returns -1 (because any of the calls to divide returned -1) then result is undefined.

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

#29
post #28

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.

Sure I can use asserts. But I'm as likely to forget the assert() as I am to forget to check the return value. And even if I did: If you consider the faulty main() in the linked article: How would you use assert() there to make sure that result as used after the call to foo() is actually usable? If foo() returns -1 (because any of the calls to divide returned -1) then result is undefined.

You would put an assert inside of the divide function like so:

  int divide (int x, int y)
  {
    defend (y != 0);
    return x / y;
  }
Now divide is guaranteed to produce a correct result if it's called with correct data. It's up to the caller to make sure the data is correct, or an assert will happen.

Just to finish out the example to show how much cleaner asserting is compared to error handling:

  int foo(void)
  {
    volatile int x = 4, y = 28;
    return divide(x, y) + divide(y, x);
  }

  int main ()
  {
    return foo();
  }
That's not to say that error handling doesn't have its place, but it should only be used for data that you can't anticipate.

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

#30

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"?

when is the binary size a more important factor than both execution speed and ease of development? Binary size (or maybe more accurately in this case, binary code layout) can be highly relevant for speed due to the instruction cache. As for ease of development, there are issues with C++ exceptions regarding this as well: some C++ libraries aren't exception safe, and neither are practically all C libraries. This is so…

Binary working set sizes are often lower with exceptions than without, because exception handling code can be moved elsewhere by the compiler. Error-checking code, on the other hand, cannot be so easily detected, and hence moved.

I think the C++ implementation of exceptions has a lot to answer for though, in poisoning too many developers on the concept. It really is an awful implementation.

Post reply on HN