Exceptions actually can need RTTI, though not necessarily all of the RTTI that things like <typeinfo> provide. For some details, see the -fno-rtti flag for GCC, for which the documentation says[1]:
Disable generation of information about every class with virtual functions for use by the C++ runtime type identification features (`dynamic_cast' and `typeid'). [...] Note that exception handling uses the same information, but it will generate it as needed.
That's great and all but when every modern compiler does implement it that way it's not something you can ignore.
Show me a compiler that's used in production which handles multi-inheritance exceptions without allocating extra data and I'll be happy to eat my words :).
The ANSI C++ standard requires exceptions in the first place. The moment we start talking about disabling them, we're not talking about standard C++ anymore.
Which is why people cannot just state "In C++ the thing X happens" without regarding what the standard says, instead of what the installed compiler does.
Language != Implementation.
If the language would be "In GCC the thing X happens when ...", then ok.
> Exceptions don't need RTTI and have only runtime cost when thrown.
No, they add extra control flow edges, which inhibit optimizations, affecting runtime performance. This is a lot of the reason why unwinding is optional in Rust.