I think a lot of it came down to the fact that when exception specifications were being defined, compiler writers were well behind the power curve. Implementing C++98 as sufficiently complex that there's only ever been one compiler that even claimed to implement all its features. Every other compiler left out at least one major feature that was included in the standard. Most fairly openly admitted that they left out substantially more than that.
You also need to keep in mind that dynamic exception specifications were also considerably more complex than just throw()
. It allows a programmer to specify an arbitrary set of types that can be thrown. Worse still, specifying that a function can throw foo
means it can also throw anything derived from foo
as well.
Enforcing exception specifications statically could have been done, but it would clearly have added quite a bit of extra work, and nobody was really sure what (if any) benefit it would provide. Under the circumstances, I think it was pretty easy for most to think that static enforcement was something that could be required later if there seemed to be enough use to justify the work. Changing from enforcing at run-time to compile-time wouldn't require modifying existing code, only existing implementations.
Another point is that I'm not sure there was ever really strong support of exception specifications anyway. I think there was general agreement on the basic idea, but when you get down to it, probably less about the details.
Bottom line: it was easy to mandate only dynamic enforcement, and leave static enforcement for later (if at all). Turns out, static enforcement probably wouldn't really add all that much positive in any case, so mandating it probably wouldn't have accomplished much anyway.