There are a lot of excellent answers how can one simulate object oriented concepts with C. To name a few:
- C double linked list with abstract data type
- C as an object oriented language
- Can you write object-oriented code in C?
When is it appropriate to use such simulation and not to use languages that support object-oriented techniques natively?
Highly related:
To just give you another example: a fair amount of the x86 Linux kernel is using C as if it were C++, when object-orientation seems natural (eg, in the VFS). The kernel is written in assembly and C (if that wasn't changed in the 3.0 kernel). The kernel coders create macros and structures, sometimes even named similar to C++ terms (eg, for_each_xxx), that allow them to code as-if. As others have pointed out, you'd never choose C if you start a heavily object-oriented program; but when you're adjusting C based code to add object-oriented features, you might.
When you want a cross-platform foundation for object-oriented APIs. A case in point is Apple's Core Foundation. Being entirely C, it could be easily ported, yet provides an extremely rich set of opaque objects to use.
A nice example of its flexibility is the way many of its types are 'toll-free' bridged with those from Foundation (a set of true OO Objective-C libraries). Many types from Core Foundation can be used, fairly naturally, in Foundation APIs, and vice-versa. It's hard to see this working so well without some OO concepts being present in the Core Foundation libraries.
I'll give you the one reason I know of because it has been the case for me:
When you are developing software for a unique platform, and the only available compiler is a C compiler. This happens quite often in the world of embedded microcontrollers.