Template libraries that have to deal with stuff that could throw vs couldn't end up with lots of nearr duplicate code, twice as much needed test coverage, and/or less efficiency if you just cover the could-throw case. And you will still probably get it wrong.
Exceptions can work ok in a GCed language, but I haven't seen them work well otherwise. Maybe it is possible, but in C++ it is a huge trap and isn't worth the extra care that will have to go into everything to avoid really bad problems.
> Template libraries that have to deal with stuff that could throw vs couldn't end up with lots of nearr duplicate code, twice as much needed test coverage, and/or less efficiency if you just cover the could-throw case. And you will still probably get it wrong.
Highly-generic container libraries constitute a tiny minority of all code, and even in this kind of code (of which I've written plenty), the tiny local optimizations that we can do if we, say, know we have a nothrow move constructor do not constitute anything near a 2x code size penalty.
You should be grateful that C++ lets you specialize code for can-fail and cannot-fail cases. Try doing that in a sloppy-exceptions language like Java.
> Exceptions can work ok in a GCed language, but I haven't seen them work well otherwise.
I have hundreds of thousands of lines of my own C++ code that say otherwise. BTW: ever hear of this weird startup called "Facebook"? All of their C++ code uses exceptions. Nevertheless, contra certain prominent C++ influencers, rivers have not flowed with blood, locusts have failed to eat the crops, and the firstborn of the nation are safe in their beds.
> Template libraries that have to deal with stuff that could throw vs couldn't end up with lots of nearr duplicate code, twice as much needed test coverage, and/or less efficiency if you just cover the could-throw case. And you will still probably get it wrong.
what are you referring to ? I have never seen template libraries having to do anything particular wrt to exceptions. If you want to throw just throw, that's the point.
It results in slower generated code and much larger binaries, neither of which would be acceptable to Google (some of their binaries are already on the brink of being unbuildable, so a bunch of junk to enable exceptions is not possible.)
the slower generated code is an academic concern. Show me a realistic/non-contrived benchmark where not keeping the stack unwindable actually helps give a useful performance increase. Error codes force people to litter the code with branches and put error handling code in the hot path of the instruction stream.
Using 'likely/unlikely' compiler directives, the instructions in the unlikely error branch can be hoisted out to another area and not significantly affect instruction cache. It still is a branch though.
and exception-based code can have much less branches since you don't need to check every function call for error but instead let the exception propagate from where they can be thrown. e.g. in a hypothetic case where you load a settings file five layers deep, in an error-code-based solution you have potentially 5 branches while in an exception-based solution you only have one
At the cost of predictable performance though. With current implementations, the exceptional path will be several magnitudes (!) slower for cheap functions.
Exceptions impose indirect costs other than just code size. For example, when std::vector reallocates, it copies instead of moves its elements, in case the move constructor throws and leaves the vector in an inconsistent state.
Exceptions can work ok in a GCed language, but I haven't seen them work well otherwise. Maybe it is possible, but in C++ it is a huge trap and isn't worth the extra care that will have to go into everything to avoid really bad problems.