I think that people treat exception specifications as specification of exceptions. Like the way that the function prototypes and the object's syntactical interface are sometimes treated as the contract and interface specification.
Indeed, there is no point in recursively embedding exceptions from the supporting functions in the specification of the caller. This is not maintainable. But if I have indexing function like vector::at, which is entirely self-contained and only performs a simple range check, then I can announce throw(std::out_of_range). Nothing else will be thrown, because I am the only one who can throw something.
Of course, nothing is gained by just specifying throw(std::out_of_range). Without knowing the conditions when I throw the exception, the client has no use for it. The same is true for argument and return types. Say, with pointer to function int (int, int), wouldn't it matter if it is addition or division operation, whether it is monotonous in each argument, whether it works outside of some finite range, etc. The type is not the entire contract, it is just the part of the contract that can be enforced by the compiler.
There are some subtleties. For example:
1 2
|
for(int i = 0; i < (int)v.size(); ++i)
sum += v.at(i);
| |
Now I may want to declare this code nothrow. But, what if vector::at contains a buffer overrun (weird, I know). Then my index may change unexpectedly to some arbitrary value and vector::at will throw the exception. However, although it is debatable, IMO the out_of_range exception would be vague anyway.
As I said, stack unwinding can be fixed with std::bad_exception and custom unexpected handler. So the clean-up problem is not really a problem, or is it?
Without the nothrow specifications, how would one implement strong exception guarantees? Regarding the performance, I actually read from the web that nothrow specifications sometimes result in better optimizations and there will be a substitute keyword in C++0x, despite that other exception specifications will be generally deprecated. Even if there are penalties, I wonder if they concern the normal program flow in the absence of exceptions. My question is, why is the feature going to be deprecated? (I can't settle the issue in my head and I just don't like to have unresolved issues like this.)
Regards
EDIT: I think I am looking at this the wrong way. The working group probably just wants to tidy their language a bit. I still think that the feature is partly blamed due to misuse. I mean, like using pointers non-portably.
EDIT 2: To state again, I don't think anyone should use exception specifications to decorate every function they have. But some methods are supposed to be minimal and self-contained by design, and consequently can meet stronger requirements without fuzz. It allows the caller to direct their effort in implementing transaction semantics. Even for a method that throws, if I am absolutely certain that there are only exceptions under conditions that are impossible in my code, then I can assume no multi-level returns.