When we declare a std::vector, or std::string, ..., like that for example
std::string hello("Hello");
isn't it wrong? shouldn't we do
std::string hello;
try {
hello = "Hello";
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
return (-1);
}
Because if I understood how it works, when an allocation fails, it will result in an uncaught exception otherwise, so why do I often see code like this ? :
std::string s("hello");
s = " world";
s = "!";
s.reserve(100);
...
without any check?
CodePudding user response:
Allocation failure is rarely checked because there is rarely a reasonable way to recover from it. What should the program do when there is no memory to do what the program needs to do? Usually, the only reasonable response is to stop what you're doing, which is exactly what happens when you don't catch the exception.
Furthermore, some language implementations don't necessarily even fail to allocate since they may over allocate memory. Such system will delay actual allocation when the memory is actually accessed.
CodePudding user response:
Most people know how memory-intensive their app is, but what are you going to do if you can't allocate a string? You probably also at that point can't do much of anything, and you're going to have to exit.
When you have actual recovery you can do, people will probably catch all exceptions at a higher level -- several method calls back, and then do what they can. Hopefully by rolling back the stack a bit, you'll release enough resources you can do whatever error handling you'd like before exiting.
CodePudding user response:
The prize question is: what do you do if you catch such an error? Unless you've got some special circumstance where you are able to recover from such an error, there is simply no point in catching it. Even in your example you simply return an error code - basically doing what the exception would have done for you otherwise, which is their entire point. You're probably just more comfortable with error returns than exceptions, which is why you prefer that scenario.
If such an exception is thrown, the next step is almost always to fail the routine that encountered it. Doing so by letting the exception bubble up is the best, least verbose way to do that. If you want to prevent crashes, add a try-catch at the entry function of whatever thread you're in, which prints the exception and exits gracefully. But, especially for debugging/testing, that often just hides useful information without providing much benefit. I prefer only catching specific errors that I can recover from in some way.