The C++ standard library defines std::runtime_error and similar to inherit from std::exception, but the inheritance is not virtual. This complicates the extension of the exception hierarchy. For example the following code has problems.
class sql_exception : public virtual std::exception {...};
class sql_disconnected : public virtual std::runtime_error, public virtual sql_exception {...};
void do_something() {
throw sql_disconnected();
}
void call_something() {
try {
do_something();
} catch (const std::exception& e) {
}
}
std::exception is being not caught, as IMHO it should be. This can be worked around in various (needlessly complicated [IMHO]) ways.
I believe the standard should permit this behavior, and since it doesn't I have to assume there is a good reason, other than "this is the standard because it is the standard".
I am aware that there is some cost associated with virtual inheritance, but AFAIK it's negligible compared to the cost of stack unwinding and the rest of the exception handling.
Q1: For what technical reason did the standard library implement this behavior?
Q2: Was the problem of extending the hierarchy considered, and if so what does the standard say about the topic? Does the standard discourage it or have a recommendation to follow?