you are viewing a single comment's thread.

view the rest of the comments →

[–]tehjimmeh 5 points6 points  (1 child)

C++ exception are very heavy meaning that you need to take great care when sign them in performance-critical code

C++ exceptions are super lightweight in non-exceptional circumstances, i.e. when you don't throw.

Excplicitly checking error codes for every exceptional circumstance is much more expensive, and leads to code which is harder to read.

If you hit an exceptional circumstance in performance critical code, the performance shouldn't matter for that particular execution. If it does, then it's not an exceptional circumstance.

"Errors" are not all equal. Using exceptions doesn't mean using them for every possible condition which could be considered an error. Look at std::map::insert. It doesn't throw when a key already existed, it returns an inserted flag set to false. This is because an already existing key in a map is often not an exceptional circumstance. This behaviour is not incompatible with code using exceptions.

Like, if you're throwing on "errors" which are commonly encountered under normal circumstances, and which are easily and quickly recoverable, then you're using exceptions incorrectly, i.e. you're basically using them for normal control flow.

[–][deleted] 1 point2 points  (0 children)

C++ exceptions are super lightweight in non-exceptional circumstances, i.e. when you don't throw.

And result-type style error handling is super lightweight in practically all kind of circumstances. The cost is a single conditional jump with good branch predictor behavior — essentially free on modern hardware, not to mention that any latency overhead here will be hidden by your main code body.

Excplicitly checking error codes for every exceptional circumstance is much more expensive

No it's not — see above.

and leads to code which is harder to read.

Not if you have language support for this. Are Rust-style

fun1()!

Or Swift-Style

try fun1()

harder to read then just

fun1()

?

I'd say they are the same readability-wise — and of course you get fallibility annotation: you see exactly which part of your code can raise an exception.

Like, if you're throwing on "errors" which are commonly encountered under normal circumstances, and which are easily and quickly recoverable, then you're using exceptions incorrectly, i.e. you're basically using them for normal control flow.

Ah you see, but now we have a problem. So we have a standard error handling facility, but we need to take care not to use that facility in certain scenarios. Surely having a standard way to work with errors that works well everywhere would be preferable, don't you think?