For reference, here is some documentation on the
exception class, which shows the hierarchy.
To my surprise,
bad_alloc derives directly from
exception, and not from
runtime_error. A catch clause for
runtime_error will not catch a
bad_alloc exception.
In many cases, I would recommend against catching all
exception objects, since some of them aren't really designed to be recovered from. I suppose you could do that when dealing with an isolated component, such as an extension module, but then the issue of exception safety comes up, and what happens if the failure corrupted your program state. Hence why not all exceptions should be caught.
Well, at the very least, given the exception hierarchy, if you want to recover from an out of memory error, it seems you do need to catch that exception specifically. My bad.
On a related note, in regards to corrupting program state. I believe the C++ exception handling mechanism may be required to allocate memory in some cases. That poses a potential problem in low memory situations. Trying to throw an exception could potentially result in an additional exception due to the low memory. I believe many implementations have a special buffer set aside for
bad_alloc in these cases, though such a system might not be entirely robust. I've read somewhere there are ways to keep exceptions alive, or chain them, and it seems the memory use for exceptions is potentially unbounded. I've read some implementations can call
terminate from within exception handling code if any of these allocations fail.
This might be why many people consider out of memory to be a fatal errors. If the exception handling system can't cope, you might be crashing anyway, whether you've tried to handle the error or not.
Though, those concerns are more when a small objects fails to be allocated. If you don't have 8 bytes or so left to store the exception, there's not much you can do. If however a large allocation failed, it might simply be the request was unreasonably large, and you do still have plenty of memory left. You might even have more memory left than was request, but it simply isn't contiguous. In short, a
bad_alloc is not the same as being out of memory, though being out of memory can result in a
bad_alloc. Assuming of course you still have the memory left for the
bad_alloc.
This doesn't instill much confidence in exceptions.