This is hard to answer without speculation, but Bjarne's 1998 paper "An Overview of the C++ Programming Language" uses arbitrary types when describing exception handling, and suggests creating a hierarchy of said types for convenient/semantics. It would seem that he did not have a "base class" of exception
in mind for any of these in the beginning.
It's possible that the notion of having a standard hierarchy (based on std::exception
) began life as an "addition", a convenient way to approach Bjarne's suggested use of exceptions, rather than the building-blocks on which everyone's use of exceptions should be based. That contemporary practice is to derive all exceptions from std::exception
would seem to have come along later.
Nowadays, I can't think of a good reason not to do that, if for no other reason than people using your code will probably expect a top-level catch (const std::exception&)
to suck up anything useful. I do also tend to put a catch (...)
in main
, though, just in case.
Speaking more practically, if this weren't the case, there would have to be additional rules constraining throw
to only be "valid" on expressions with type deriving from std::exception
, which would not seem to have any real-world benefit sufficient to justify the additional rules. C++, believe it or not, comes from a place of minimalism in terms of the question "why don't we have such-and-such a rule", although obviously its bloat would seem to contradict this after all these years.
I doubt this has anything to do with using throw
for non-exceptional things, because that has always been considered bad practice. The way Bjarne describes this feature is:
Exceptions are used to transfer control from a place where an error is detected to some caller that hasexpressed interest in handling that kind of errors. Clearly, this is a mechanism that should be used only for errors that cannot be handled locally. [..] Exceptions can be used to make error handling more stylized and regular.
So it's clear that at least the original design intent (and, again, this is still common wisdom) is to use exceptions for exceptional/errory cases only.