I got a very nice response from Nathan Myers to my previous diary entry, explaining more or less what was going on. He is the author of the libstdc++-v3 string class, which is much better written.
While I'm in the C++ vein, exception specifications suck. My manager at work decided we were going to "make the best of them" by using them to ensure that all exceptions were derived from the "std::exception" class and no weirdo strings or ADTs were being thrown. Thus, every function would declare either throw() or throw(exception).
I wasn't able to stay for the original meeting where this was discussed, but I've tried to present a three-fold argument why this is a bad idea.
- Our coding conventions pretty much determine which functions can throw exceptions and which can't, so the documentation value of the specification is nil.
- The cost of the run-time check done caused by an exception specification is too expensive for the benefit gained.
- There are other ways of guaranteeing the property he cares about, such as using a compiler with semantic checking modules.
The problem with C++ exception specifications was that a decision was made to not force them to be checked at compile time. (Unlike Java, where exception types are checked by the compiler and thus don't need to be verified at run time.) This makes a certain amount of sense in that much code won't use exception specifications and thus has to be assumed to throw anything. But if the compiler doesn't (or can't) aggressively optimize out run-time checks, then you suffer a pretty significant performance loss.
I did a microbenchmark to try to quantify my point #2. Briefly, I found that a function call which took 7 ns before (including loop iteration overhead) took 20 ns with a throw() specification and 23 ns with a throw(exception) specification. For a programming style that uses lots of function calls, this is pretty troubling. Using a profile of an existing program, I estimated that this would increase (user-level) run-time by about 5%--- even in a program which spent half of its time calling read(), write(), memcpy(), malloc(), and one application-specific bit-fiddling routine.
Of course this isn't a substitute for actually trying it out on a real program, but who has time for that?