To quote the recent HOPL paper by Bjarne:
Page 62: "There was always a group of people who wanted compile-time checks of which exceptions a
function could throw. That, of course, works well in type theory, with small programs, with fast
compilers, and with full control of the source code. The committee repeatedly rejected that idea on
the grounds that it doesn’t scale to million-line programs developed and maintained by dozens (or
more) organizations."
Concretely, one of the ways C++ lets you write big programs "without full control of the source code" is templates.
Andrey, you'd have to figure out what to do about templates:
struct ErrA {};
struct ErrB {};
struct SA {
void foo() throw(ErrA);
};
struct SB {
void foo() throw(ErrB);
};
template<class T>
void foo(T t) throw(???) {
t.foo();
}
C++ already has several properties that can be propagated from callee to caller with enough effort: noexceptness, well-formedness (SFINAE).
It has a few that cannot be propagated without loss: explicitness, overload-resolution-priority, constrainedness (C++20).
At the moment, you're asking to add another property that can't be propagated. Can you fix that somehow?
Herb Sutter's "Herbceptions" have basically the same problem with templates (last I checked): they add a new property that we'd like to propagate but it is ugly and/or inefficient to do so. I refer to these kinds of property as "colorations"; see e.g.
In general I kind of like the idea of statically checking "this function may yield a result or an ErrA, and so all callers must handle ErrA"; but if you're actually in that situation today, why not just return a `variant` or `Expected` type instead? C++ exceptions are what you use when you want the set of yieldable things to be open-ended.
–Arthur