> I've never seen RTTI use in production code.
I have, but it's almost never the extremely limited built-in RTTI.
> Except for maybe some tiny embedded systems (like microcontrollers), the overhead of exceptions isn't that bad any more.
Big caveat here: Unthrown / rare exceptions aren't that bad.
I ran into a bug with the windows 8 touch APIs, where the pointer ID for a given finger would become invalid just before we recieved the "pointer up" notification if you pawed at the screen in just the right way. This manifested as an exception being thrown when querying the pointer position - which, of course, wasn't caught, meaning pawing at the screen just right crashed the program.
Catching the exception stopped it from crashing, at least. But the framerate would tank if you pawed at the screen, from exception handling overhead alone.
I've come to frown on exceptions in C++, for production gamedev. Everything else is using error codes anyways, why add a second error handling style into the mix? Your callbacks may be invoked from third party C, which you can't safely throw across, or C++ built with exceptions disabled, which you also can't safely throw across. Heck, just building with exceptions enabled can be difficult - I could not link against some of the C++ PS4 libraries without matching many of their build settings - including having exception handling disabled.
...I resorted to alternative options for handling failed unit tests.