@computerquip
You're probably right.
ne555 wrote: |
---|
the process needs a resource, it does not obtain it, so it has nothing to do.
simply terminating the process is quite a waste
saving its state could take a really long time. Maybe long enough that other process release some memory.
so let's wait. |
That's true.
PS: I don't like using exceptions as error codes. |
Personally I find them superior to return values, although I understand there is (probably very small) a performance hit. I prefer exceptions for a few reasons:
* they don't require all your functions that may fail to return a type that can indicate failure (like bool, int or T*)
* functions which return references can indicate failure if you use exceptions, but not if you only use return values (unless you use output parameters, but I don't like to do that; I think parameters should be for defining the function's behaviour and return values for describing the result)
* with return values, if a calling function doesn't want to handle errors (e.g. if it wants to just die when something bad happens) it still needs error checking code:
1 2 3 4 5 6 7 8
|
void caller()
{
if (callee() < 0) {
// Manually commit seppuku when callee fails.
std::cerr << "Error occurred\n";
std::terminate();
}
}
| |
whereas, with exceptions,
1 2 3 4 5
|
void caller()
{
callee();
// Automatically dies if callee throws an exception.
}
| |
* exceptions are more consistent because an exception always indicates failure† whereas the meaning of a return value differs between different functions and APIs, e.g. some functions return -1 to indicate failure, some functions return false, some return NULL (or nullptr), some may use a different positive integer for each error case -- consistency is not as enforced as it is with exceptions
*
http://www.parashift.com/c++-faq/exceptions-eliminate-ifs.html
*
http://www.parashift.com/c++-faq/exceptions-avoid-two-return-types.html
I almost exclusively use return values for when I'm trying to get a value (which is what they're for). Your code example would be a situation where I might use one to indicate failure because that loop would be more complex otherwise, but generally speaking, I don't use them for that in C++.
† unless you were doing something really weird, like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
void thrower()
{
std::string line;
std::cout << "What is your name? ";
std::getline(std::cin, line);
throw line;
}
void catcher()
{
try {
thrower();
} catch (const std::string& name) {
std::cout << "Hello, " << name << '\n';
}
}
| |
but, knowing that it's called an
exception, and knowing what the word "exception" means, you would have to be using it wrong intentionally. There's no way someone who knows what "exception" means could do it by accident. That said, I think maybe C++ should make sure only types derived from std::exception are throwable.