3 ms·
The webpage in the title is pretty good. It explains most things you need to achieve OOP in C. This PDF however pushes C for what it is not intended for, which
by attractivechaos 4y ago
The webpage in the title is pretty good. It explains most things you need to achieve OOP in C. This PDF however pushes C for what it is not intended for, which leads to inefficient and obscure code.
For example, the first example in the PDF implements a Set. Everything is "void". This loses typing and will make code hard to read and maintain. The way inheritance is mimicked is hideous and inefficient. The PDF also heavily uses function pointers, which can be slow (because they aren't easily inlined) and waste memory (because each pointer costs 8 bytes on x64).
In all, most large C projects are doing OOP at some level. However, C is not C++ and is not intended for providing all OOP features like inheritance. This book should probably be titled "Wrong ways to OOP in C".
PS: The book does have some interesting ideas, but those are the "clever" things you will have to unlearn later. The author provides the source code for the book [1]. Have a look at the string implementation in Chapter Two. That is the most arcane and inefficient string implementation I have seen.
[1] https://www.cs.rit.edu/~ats/books/ooc-14.01.03.tar.gz https://www.cs.rit.edu/~ats/books/ooc-14.01.03.tar.gz
- sfpotter 4y agoThis book is a really fun read. You’ll learn a lot and get some interesting ideas. Don’t listen to prescriptions from strangers on HN, how about? Myself included. :-)
- quelsolaar 4y agoI have not read the book. > However, C is not C++ and is not intended for providing all OOP features like inheritance. There are parts of the ISO C standard specifically included to allow for inheritance. Consider: typedef struct{ int x; }struct_a; typedef struct{ struct_a inherited; int y; }struct_b; void function(struct_a *s) { s->x = 0; } Here struct_b inharates struct_a. You can call the function with either a pointer to struct_a or struct_b (either by casing or void pointer), because the standard specifically states that there can be no padding before the first member of a structure, so that the first member of a structure should have the same pointer as the structure itself. This part of the spec was written with the use case of inheritance in mind. (there is some people who don't read the spec that way, but this is the intention) Sorry for being nitpicky... but that's pretty much what we do in the wg14....
- orlp 4y agoDoesn't this violate strict aliasing? E.g. what if we do this? void foo(struct_a *a, struct_b *b) { a->x = 0; b->x += 1; a->x = 0; } Strict aliasing allows the compiler to elide the second a->x = 0. But if we use your inheritance scheme using casting of pointers, we could have a == b.