If the error will stop the program flow and show a warning dialog to the user, it's useless to think too much about performance. More or less the same if it's going to log some message and abort the operation.
What is usually frowned upon is using the exception as a kind of goto for normal flow of the program. Exceptions should be... the exception.
Otherwise all this performance brouhaha is a waste of time.
:)
Exceptions are just “goto whatever catch is in the call stack”.
It’s still completely obvious when you see a throw statement that it can throw, and static analysis can tell you exactly what can be thrown by each function.
It is the same "problem" as not knowing where a return will return to.
You can't "just" search for function name, you have to rely on code analysis tools.
Making code more opaque coz you can get thru the mess of it via tooling is terrible direction
“Who will catch this” is supposed to be opaque. It’s like wondering who will call this function.
If you want to goto some specific point in the code, just call it.
That's not how idiomatic C++ is. Nor Rust. Nor Go.
One of Java's (incl standard library) main design flaws is overuse of exceptions.
It should not be emulated. It's too late to fix Java, but that doesn't make it a good idea.
I would not call std::optional in C++ any form of checked exception, and the difference isn't that std::optional doesn't carry value-missing metadata.
If you exit the program on error, this does work in some cases like command-line utilities, but your users would not be happy if your GUI app crashes when you open a malformed file.
But since you brought it up ;) I bounce back and forth between which approach I like. Sometimes exceptions seem bulky and unwieldy and honestly a bit lazy. Returning an error feels verbose and annoying and bulky as well. But it also feels like returning an error forces you to think about what should happen, where exceptions let you kick the can down the road.
Neither are great, but I find that code that uses exceptions ends up being poorer in design and functioning, but also errors-on-return tends to be harder to read.
Yes, I called it "idiomatic C++" before, but reasonable people disagree about the best option.
Smarter people than me have written good things in the E section of the C++ Core Guidelines. The people involved have overlap with the C++ standards committee:
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#...
At least if you use exceptions for errors C++ doesn't need "finally", because it has working RAII, unlike Java.
try(FileInputStream in=new FileInputStream(file)){
// do something with the file data
}catch(IOException x){
x.printStackTrace();
}
It's been a very long time since I last wrote "something.close()".C++ throws on memory allocation error, but that's about it. Memory allocation errors are special in all languages. Because of lazy allocation and overcommit, unless you specifically set your environment to work otherwise, your program will probably just crash when it gets its first page fault that can't be honored.
Open a file? fstream sets .is_open() (or its operator bool, so just "if (!f)")
Write fails? Sets .fail()
POSIX stuff usually return an error code, and set errno.
Modern C++ has std::optional.
But there's of course another answer to this, and that is "C++ has zero cost abstractions", meaning for example if you don't check for nullptr, then neither will the language. There's no NullPointerException because C++ just says that this is Undefined Behavior.
Oh, here's one: If you use dynamic_cast to try to downcast into the wrong type, that'll throw an exception. But first of all: don't downcast, and second of all: This is not an "unexpected input to function". This is a complete programming error and it's probably best to terminate. I.e. this is something Go style would panic about, not return an error.
Do you have more specific examples about unexpected input to a function that you would want to return an error for?
Ugh. Actually std::stoi() violates this pattern. If std::optional existed in C++11 it would probably have been used here.
Actually no, not in Java! You can catch java.lang.OutOfMemoryError just like any other exception. If the memory pressure is high though, it's possible that another OOM would be thrown from the code that handles it.
But when memory pressure is high you can get killed at any time. E.g. on Linux the OOM killer might decide that it's best for the system that your process dies, even if you've not done memory allocations or needed to page fault for hours.
IIRC OpenBSD doesn't overcommit memory, but in my experience its system stability is much worse when memory is low.
Goto is used often in C parsers for a reason, because it is easier to reason that way when you're validating something rather than using deeply nested branches. People shit on goto because of dijkstra's paper but few people have even read that paper and fewer even know that it is the origin of "x considered harmful" meme.
Goto is a boon. Anytime people use exceptions like how you are you're just admitting you're itching for a goto and your language doesn't provide it. And thus you shouldn't clutch your pearls when others use it in c.
This fits within my understanding of a reasonable use for exceptions - usually these are in the form of assertions, which themselves throw exceptions but can be turned off at runtime if you don't expect to ever see this condition in real production circumstances.
the example shows an extra time of 500nanoseconds when not throwing. this is 0.005 milliseconds. if your api takes more than 1ms then changing it to not throw will not be noticeable. even if the exception time cost was 10x higher and it took 0.05ms longer it would not be noticeable