C++ exceptions are not checked at compile-time like Java exceptions (excluding Java's unchecked RuntimeExceptions). The C++ throw() specifier is a run-time check that aborts your program if an exception not listed in the throw() specifier escapes the function.
C++'s design combines the worst of checked and unchecked exceptions and adds some additional run-time overhead for good measure. Writing exception-safe C++ code is essentially impractical for large C++ programs that include C libraries unless you write your own RAII classes for everything. But then your C++ code is littered with unreadable std::shared_ptr<whatever> everywhere. If C++11 had adopted some Rust-like shorthand syntax for std::shared_ptr and std::unique_ptr, it might actually be palatable.
Unless I am mistaken, on 32bit platforms exceptions incur a runtime overhead but for 64bit zero cost exceptions were developed, and only incur overhead if they are triggered [3]
I'm not familiar with C++11's noexcept specifier, but the throw() example from [1] shows how throwing a W object is caught at run-time instead of compile-time. I think compile-time exception checking is infeasible because C++ functions without a throw() specifier might throw any exception, so the caller can't actually check at compile-time what exceptions might be thrown.
void f() throw(X, Y)
{
int n = 0;
if (n) throw X(); // OK
if (n) throw Z(); // also OK
throw W(); // will call std::unexpected() at run-time, not a compile-time error
}
C++'s design combines the worst of checked and unchecked exceptions and adds some additional run-time overhead for good measure. Writing exception-safe C++ code is essentially impractical for large C++ programs that include C libraries unless you write your own RAII classes for everything. But then your C++ code is littered with unreadable std::shared_ptr<whatever> everywhere. If C++11 had adopted some Rust-like shorthand syntax for std::shared_ptr and std::unique_ptr, it might actually be palatable.