It's worth pointing out that Gnome, one of the two major GUIs for Linux (and other Unices), is chock full of #2. (It's the only modern GUI I'm aware of that is implemented primarily in a non-OO language.) The surprising thing is that it usually works quite well...
GObject, the C-language object system used in Gnome, Gtk and other libraries, implements its own runtime type checking system, so is really of type #1.
Perhaps; though doing typechecking in a bunch of macros isn't as neat and clean as doing it in the language proper. Writing code for GObject is truly ugly....--ScottJohnson
Bah, PointerCastPolymorphism is one of those things like ExplicitMemoryManagement: easy to do wrong, causes programming overhead, ugly (if one is used to something better), but works just fine when the programmer knows what e's doing and chooses a universal set of rules. It's easy enough to do e.g. ComponentObjectModel programming in C; Flux OsKit does that quite neatly.
For more examples of PointerCastPolymorphism, simply look to any of the older OpenSource programming languages. Most of them implement polymorphism, and themselves are implemented in CeeLanguage, and so as such are chock full of manual refcounting, manual polymorphism, and various other features. PythonLanguage is a particularly good example of this to look at, since it's system is designed to be easily extended by users for the purpose making custom Python types in CeeLanguage (a tricky, but not painful, process).
See also PointerMetaprogramming and some discussion on FirstClass.