9 ms·
Object oriented programming with ANSI-C (1993) [pdf]
- kasajian 9y agoAnother article related to this: https://www.codeproject.com/Articles/22139/Simply-Object-Oriented-C https://www.codeproject.com/Articles/22139/Simply-Object-Ori... I wrote it a while back just to see what I would come up with if I had to solve that problem for myself using only macros.
- sesteel 9y agoThis is one of my favorite reads. About 10 years ago I was developing a toy programming language that compiled to ANSI-C and this was a great resource to me at the time.
- Koshkin 9y ago> void * find (const void * _set, const void * _element) Such an eye sore, and I think it goes strongly against the tradition of coding in C when someone uses the asterisk in the pointer context in such a way that makes it look like an infix operator, i.e. as if it was multiplication. As to achieving a reasonably looking OO in C, this is why C++ was born...
- 4lch3m1st 9y agoAnytime I write C code, I try to keep the asterisk close to the type: void* foo(void* bar); I know that the asterisk technically belongs with the variable name when declaring it, but it helps to wrap my head around them, as a reminder that they're a pointer type.
- sigjuice 9y agoThe world mostly does it the other way. A couple of code examples: https://github.com/apache/httpd/blob/trunk/server/provider.c https://github.com/apache/httpd/blob/trunk/server/provider.c https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/fork.c https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.... Almost all documentation, references and literature: Here are a couple of man pages. http://man7.org/linux/man-pages/man3/gethostbyname.3.html http://man7.org/linux/man-pages/man3/gethostbyname.3.html https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/execv.3.html https://developer.apple.com/library/mac/documentation/Darwin... Here is a draft of the ISO C standard: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
- ngcc_hk 9y agoI agree you based on fact that more in code we use void *s = then use it as s= But I agree more that the void* s = then use it as s= Is more understandable as the first set confuse me when I learn pointer. It still does. void* is a type like statement. And void is like a return type statement.
- millstone 9y agoThis totally destroyed me when I was learning C. The theory was: int *foo; makes more sense, because to access the int, you write: *foo = ...; But that's not an int, it's a crash! If you want an int, you have to make one. Placing the asterisk next to the type made it all click for me.
- Y_Y 9y agodouble foo; compute(foo); That's not even a crash, just silent garbage. I don't know how you expect to do better with an uninitialised variable (except ints that default to 0). foo dereferences to an int, but what could you hope to happen if you never gave it some memory to point to?
- jcelerier 9y agoThe only thing that sucks hard is when you do : int* s1, s2; here s2 is an int, not an int* and you have to do int* s1, *s2; this is braindead imho
- megaman22 9y agoAs long as you're not using prehistoric versions if C, you don't have to define all variables up front, so there is much less justifiable reasons for that kind of multiple declaration.
- Koshkin 9y agoExcept nothing will save you from the "one true way to write C" when you try to write a declaration of a pointer to a function, for example.
- yawaramin 9y agoThe first chapter, on abstraction and information hiding, is probably the most important. Every programmer should know how to do it. It's one of C's main strengths that it allows abstract data types so easily. ADTs in fact allow better binary compatibility since you only expose pointers as your public API, not structures of different shapes and sizes. I'm continually surprised by how often people insist on putting struct definitions right in their header files, defeating the whole idea of type abstraction.
- Koshkin 9y ago> It's one of C's main strengths that it allows abstract data types so easily. On the contrary, data type abstraction in C is a pain. This was one of the reasons for creation of "C with classes" (a.k.a. C++).
- catnaroek 9y agoNot that C++ is particularly good at data abstraction either.
- ASalazarMX 9y agoI prefer to call it "C Gone Wild".
- dangerbird2 9y agoThe only things that are particularly painful about opaque types in C is that you can't easily use stack-based memory to allocate opaque objects. This of course is true for C++ opaque types, but people tend to rely on private fields of concrete types instead of "PIMPL" struct declarations, even though the latter is arguably better for binary compatability and information hiding.
- catnaroek 9y agoNot that object-oriented languages are particularly good at it, but defining and using abstract data types in C is a pain: (0) Forward declarations are the only way not to explicitly reveal the representation of types, but you have to pay an indirection tax for it, whether you actually need indirection or don't. (1) Without heavily abusing the preprocessor, there is no way to express the fact that two abstract data types expose the same interface. (2) Again, without heavily abusing the preprocessor, there is no way to make common algorithms work on abstract data types that have a common interface.
- kuwze 9y agoReminded me of the C Object System by Laurent Deniau[0]. [0]: http://ldeniau.web.cern.ch/ldeniau/cos.html http://ldeniau.web.cern.ch/ldeniau/cos.html
- wybiral 9y agoOne thing that was really educational for me was reading how CPython implemented their object system. https://github.com/python/cpython/blob/master/Include/object.h https://github.com/python/cpython/blob/master/Include/object... Basically objects are structs that all share the same header which contains a pointer to the object type (ob_type) and the reference count (ob_refcnt) for memory management. That way you can always cast back to a pointer of that header struct and access ob_type and ob_refcnt no matter what the actual implemented struct contains afterwards. ob_type contains the name of the type and function pointers for common methods used by objects (getattr, setattr, hash, arithmetic, etc).
- pakl 9y agoI am a fan of libco2[1] which is a minimalist object-oriented layer on top of C. [1] https://github.com/peterpaul/co2/tree/master/examples/my-object-carbon/src https://github.com/peterpaul/co2/tree/master/examples/my-obj...
- pdfernhout 9y agoI wrote an AI Expert article on a similar theme ("Simulating Intelligent Interacting Objects in C", AI Expert, January 1989) about using C for OO programming of a robot simulator -- where the first argument is a pointer to a data structure representing the object. I prefixed all the function names with the class name, like Robot_move(robot, x, y). I was inspired by IIRC Eric Schildt's previous article elsewhere on how OO is an attitude. Looks like a very comprehensive book though compared to just some short articles (even if it does not cite those as previous work). In general, this idea of opaque handles was (and is) very common in C programming, like with file operations. So, the question is what conventions we use or what convenience superstructure we build around that basic idea of handles.
- jacinabox 9y agoFor me the notion of domain is helpful in understanding OO. The definition of a domain is that everything inside it stands in determinate relations, whereas while multiple domains can interact they don't stand in determinate relations. Inheritance in classes, in adding more features to a class, can also have knock-on effects that interfere with the assumptions of other classes that are closely coupled to it, making classes an example of domain. Whole computers in a network are also domains; nodes can go down in which case no determinate expectations can be placed on them. The existence of multiple domains is essentially postmodern as it creates, for practical purposes, multiple sources of truth. Because the expectations of one domain on another are weak, this naturally leads to a domain becoming robust against errors and inconsistencies from other domains, which leads to a stronger system. This type of robustness also helps components still be valid when they are placed into a different theory/environment that has additional properties. In some sense FP and OO are aiming at the same thing, that is making definitions that remain valid when the "arrows" of their environment change their meaning. For a different perspective on this see Gerald Jay Sussman, "We Really Don't Know How to Compute!"