On 10/02/2016 09:04, Emil Dotchevski wrote:
The use of error codes in low level APIs is a fact of life, since most of that code is written in C anyway. I wouldn't call it optimal in C++, I personally convert error codes into exceptions at the earliest possible opportunity. As for runtime overhead, like I said already, where it matters it can be easily deleted, by inlining; and, in such contexts you need to inline with or without exception handling: I've never seen a case where I could afford the overhead of a function call but could not afford the exception handling overhead in the same function.
The overhead of exception-handling plumbing that is not actually exercised is typically minimal and not worth worrying about unless you're in one of those contexts where you begrudge every method call, as you've said. The overhead of a thrown exception is larger, particularly on those systems where throwing an exception also captures a stack trace (which is incredibly helpful for debugging, but sadly often quite expensive). The overhead of dealing with error return codes for uncommon failures is also fairly large, with the risk of ignoring them and ending up in weird states. The trick is to find the balance between them, with the complication that it may not be known at the library level which failures are exceptional and which are expected. As an example, I can imagine that most applications don't want a "delete file" method to throw an exception if the file is already absent -- but there might be some transactional systems in which that would be a serious problem, and checking for existence beforehand might not be sufficient as it would still be a race condition. This sort of thing could be a good argument for "degrees of success", where eg. the above delete call returns success in both cases but can also indicate that the file was already missing and it did nothing. (Which is trivial in this case since it can be done with a simple bool return value, but you can probably imagine other cases where it might make sense to return both a T and a non-error status value of some kind.)