What would be a set of nifty preprocessor hacks (ANSI C89/ISO C90 compatible) which enable some kind of ugly (but usable) object-orientation in C?
I am familiar with a few different object-oriented languages, so please don't respond with answers like "Learn C++!". I have read "Object-Oriented Programming With ANSI C" (beware: PDF format) and several other interesting solutions, but I'm mostly interested in yours :-)!
I'm a bit late to the party here but I like to avoid both macro extremes - too many or too much obfuscates code, but a couple obvious macros can make the OOP code easier to develop and read:
I think this has a good balance, and the errors it generates (at least with default gcc 6.3 options) for some of the more likely mistakes are helpful instead of confusing. The whole point is to improve programmer productivity no?
C Object System (COS) sounds promising (it's still in alpha version). It tries to keep minimal the available concepts for the sake of simplicity and flexibility: uniform object oriented programming including open classes, metaclasses, property metaclasses, generics, multimethods, delegation, ownership, exceptions, contracts and closures. There is a draft paper (PDF) that describes it.
Exception in C is a C89 implementation of the TRY-CATCH-FINALLY found in other OO languages. It comes with a testsuite and some examples.
Both by Laurent Deniau, which is working a lot on OOP in C.
If you really thinks catefully, even standard C library use OOP - consider
FILE *
as an example:fopen()
initializes anFILE *
object, and you use it use member methodsfscanf()
,fprintf()
,fread()
,fwrite()
and others, and eventually finalize it withfclose()
.You can also go with the pseudo-Objective-C way which is not difficult as well:
To use:
This is what may be resulted from some Objective-C code like this, if a pretty-old Objective-C-to-C translator is used:
Slightly off-topic, but the original C++ compiler, Cfront, compiled C++ to C and then to assembler.
Preserved here.
If I were going to write OOP in C I would probably go with a pseudo-Pimpl design. Instead of passing pointers to structs, you end up passing pointers to pointers to structs. This makes the content opaque and facilitates polymorphism and inheritance.
The real problem with OOP in C is what happens when variables exit scope. There are no compiler-generated destructors and that can cause issues. Macros can possibly help, but it is always going to be ugly to look at.
Look at http://ldeniau.web.cern.ch/ldeniau/html/oopc/oopc.html. If nothing else reading through the documentation is an enlightening experience.