> The article describes how the Linux kernel, despite being written in C, embraces object-oriented principles by using function pointers in structures to achieve polymorphism. This technique predates object oriented programming. It is called an abstract data type or data abstraction. A key difference between data abstraction and object oriented programming is that you can leave functions unimplemented in your abstrac…
Inheritance is not needed when a composite pattern can be used. class DefaultTask { } class SpecialTask { } class UsedItem { UsedItem() { _task = new SpecialTask() } void DoIt() { _task.DoIt() } } Is python a OOP language? Self / this / object pointer has to be passed similar to using C style object-oriented / data abstraction.
Object-oriented design patterns in C and kernel development
51–60 of 224 posts
Re: Object-oriented design patterns in C and kernel development
#52Earlier quoted context omitted.
I largely agree, and use these patterns in C, but you’re neglecting the usual approach of having a default or stub implementation in the base for classic OOP. There’s also the option of using interfaces in more modern OOP or concept-style languages where you can cast to an interface type to only require the subset of the API you actually need to call. Go is a good example of this, in fact doing the lookup at runtime…
My point is that this pattern is not object oriented programming. As for a default behavior with it, you usually would do that by either always adding the default pointer when creating the structure or calling the default whenever the pointer is NULL. In the Linux VFS for example, there are optimized functions for reading and writing, but if those are not implemented, a fallback to unoptimized functions is done at th…
Isn't this exactly how most (every?) OOP language implements it? You would say a C++ virtual method isn't OOP?
Re: Object-oriented design patterns in C and kernel development
#53> The article describes how the Linux kernel, despite being written in C, embraces object-oriented principles by using function pointers in structures to achieve polymorphism. This technique predates object oriented programming. It is called an abstract data type or data abstraction. A key difference between data abstraction and object oriented programming is that you can leave functions unimplemented in your abstrac…
Inheritance is not needed when a composite pattern can be used. class DefaultTask { } class SpecialTask { } class UsedItem { UsedItem() { _task = new SpecialTask() } void DoIt() { _task.DoIt() } } Is python a OOP language? Self / this / object pointer has to be passed similar to using C style object-oriented / data abstraction.
Re: Object-oriented design patterns in C and kernel development
#54Earlier quoted context omitted.
In Smalltalk and Objective-C, you just check at runtime whether an object instance responds to a message. This is the original OOP way. It's sad that OOP was corrupted by the excessively class-centric C++ and Java design patterns.
> In Smalltalk and Objective-C, you just check at runtime whether an object instance responds to a message. This is the original OOP way. This introduces performance issues larger than the typical ones associated with vtable lookups. Not all domains can afford this today and even fewer in the 80s/90s when these languages were first designed. > It's sad that OOP was corrupted by the excessively class-centric C++ and J…
Don't know about other programming languages but with Objective-C due to IMP caching the performance is close to C++ vtable
Name Iterations Total time (sec) Time per (ns)
C++ virtual method call 1000000000 1.5 1.5
IMP-cached message send 1000000000 1.6 1.6
https://mikeash.com/pyblog/friday-qa-2016-04-15-performance-...Re: Object-oriented design patterns in C and kernel development
#55I always wonder, why not anything similar made it into a new (some) C version? Clearly, there is a significant demand for - lots of people reimplementing the same (similar) set of patterns.
Re: Object-oriented design patterns in C and kernel development
#56Earlier quoted context omitted.
“this” is a reserved keyword in C++, so you do not need to worry about it being a global variable. That said, I like having a this pointer explicitly passed as it is in C with ADTs. The functions that do not need a this pointer never accidentally have it passed from the developer forgetting to mark the function static or not wanting to rewrite all of the function accesses to use the :: operator.
It’s not about ‘this’ being a global, it’s if you see ‘i++’ in code it’s not obvious if ‘i’ is a member or not without having to check context.
Re: Object-oriented design patterns in C and kernel development
#57Earlier quoted context omitted.
I think both of these invocations are invalid. Using object1's vtable methods on object2, obviously, but in the latter case: the vtable method should just point at the superclass impl, if not overridden. And if overridden and the child impl needs to call the superclass, it can just do so without dispatching through some vtable.
When you think of vtables as unique or owned by an object, then these example seem weird to you. When you think of them as orthogonal to your types/objects, these examples can be useful. In the first example, object1 and object2 can very much be of the same type or compatible types/subtypes/supertypes. Having vtables per object as opposed to per class to me indicates, that it IS intended to modify the behaviour of an…
Re: Object-oriented design patterns in C and kernel development
#58Earlier quoted context omitted.
It’s not about ‘this’ being a global, it’s if you see ‘i++’ in code it’s not obvious if ‘i’ is a member or not without having to check context.
If you see "i++" in code and you don't have any context about what "i" is, then what difference does it make if "i" is a member variable, global variable, parameter, etc etc... If all you see in code is a very tiny 3 character expression, you won't be able to make much of a judgement about it to begin with.
Re: Object-oriented design patterns in C and kernel development
#59A few years ago Peterpaul developed a lightweight object-oriented system on top of C that was really pleasant to use[0]. No need to pass in the object explicitly, etc. Doesn't have the greatest documentation, but has a full test suite (e.g., [1][2]). [0] https://github.com/peterpaul/co2 [1] https://github.com/peterpaul/co2/blob/master/carbon/test/pas... [2] https://github.com/peterpaul/co2/blob/master/carbon/test/pas…
0. https://github.com/peterpaul/co2/tree/master/examples/my-obj...
Re: Object-oriented design patterns in C and kernel development
#60Yup. I've often wonder why the aversion to C++ since they are obviously using objects. Is it that they don't want to also enable all the C++ language junk like templates or OO junk like inheritance?
The C syntax is not really that complicated. Dynamic dispatch and virtual methods was already in the article. Here is inheritance:
struct Subclass {
struct Baseclass base;
};
That's not really that complicated. Sure, you need to encapsulate every method of the parent class, if you want to expose it. But you are also recommended to do that in other languages, and if you subclass you probably want to slightly modify behaviour anyway.As for stuff like templates: C doesn't thinks everything needs to be in the compiler. For example shadowing and hiding symbols can be done by the linker, since this is the component that handles symbol resolution across different units anyway. When you want templates, either you actually want a cheap way of runtime dynamism, then do that, or you want source code generation. Why does the compiler need to do that? For the basics there is a separate tool in the language: the Preprocessor, if you want more, you are free to choose your tool. If you want a macro language, there is e.g. M4. If you want another generator just use it. If you feel no tool really cuts it, why don't you write your code generator in C?