The jaundiced C programmer's view of object orientation
Back in an entry on inheritance versus interfaces I mentioned that I had what I said could be called the jaundiced C programmer's view of inheritance. That label deserves an explanation and today is when I finally write it.
C has no inherent OO support (all of that arrived in C++); no syntax for it, no standard for it, no anything. Never the less, everyone writing a large program in C rapidly winds up implementing any number of OO features in the code (using 'design patterns' that are well known by experienced C programmers). Any sufficiently large C program will contain at least one object system (implementing some kind of polymorphism) and a version of generic method dispatch; often you will also find some sort of inheritance. Many systems will have what can pass for (specialized) multiple inheritance as well.
C programmers do not code all of these things because we secretly want to work in an OO language. We write these things because they make the code simpler, shorter, and easier to understand. This gives experienced C programmers a very functional and cynical view of what OO is about. In C, OO is not about purity or doing things the proper way, it's about saving effort and making code easier to write. You don't do the 'OO' thing, whatever that is; instead you do whatever's simplest and clearest. If OO is the right answer, it falls out of the code in the end all on its own, emerging from the natural, logical structure of your program. An experienced C programmer recognizes situations where an OO design makes sense and knows how to put together one of the standard patterns for implementing it, but they also know better than to force OO patterns on code that doesn't call for it.
Further, C programmers often discover the basics of these OO patterns on their own just through simplifying and streamlining their own code. It doesn't take much writing of repetitive boilerplate before a C programmer starts thinking of tricks like indirecting through function pointers and embedding common elements at the start of structures so that you can make functions generic, and then you turn around and you've derived primitive OO all on your own. When you and your code go through this learning experience, the whole thing sticks with you fairly vividly (or at least it did for me).
(The corollary to this is that studying any sufficiently large, reasonably well done C codebase will show you all of the OO-in-C design patterns that you could ever want. One good example of this is the Linux kernel, which is just riddled with OO-in-C code and data structures. In general, any time you find C code with function pointers in a structure (or a structure with a pointer to another structure with function pointers), you've found some OO code.)