Object-oriented design patterns in C and kernel development
Is this OOP or “just” data abstraction?
- One camp argues the kernel’s function-pointer structs are classic Abstract Data Types (ADTs) that predate OOP, not OOP itself.
- They stress key differences:
- ADTs can have unimplemented function pointers (NULL or stub), instantiated freely.
- OOP (in mainstream languages) enforces contracts via the compiler: pure virtual methods must be implemented before instantiation, inheritance rules, implicit
this,Base::method()access, etc.
- Others argue that if you have data + behavior + dynamic dispatch via tables of function pointers, that is object-oriented, regardless of language support; ADTs and OOP overlap heavily.
What is a vtable, really?
- Long sub-thread debates whether Linux structs like
file_operations/inode_operationsare vtables. - Objections: these tables can contain functions without a
this-like parameter and even “static-like” operations; there’s no inheritance hierarchy, so calling them vtables is misleading. - Counterpoint: a “vtable” is any table of functions used for dynamic dispatch; whether the compiler or programmer builds it, or whether every entry takes a
this, is seen as an implementation detail by some.
Dynamic dispatch styles and language contrasts
- Discussion contrasts:
- C/Unix style: explicit struct-of-function-pointers, sometimes NULL-checked or stubbed; optional behavior and mutually exclusive ops are easy.
- C++/Java: compiler-managed vtables, pure virtuals, class-centric inheritance, stronger contracts but less flexibility.
- Smalltalk/Objective‑C: message passing, runtime “does this object respond?” checks,
method_missing/doesNotUnderstand-style patterns, more dynamic but potentially slower (though Obj‑C dispatch can approach C++ vtable performance via caching). - Go/modern languages: interface/table-of-functions model that’s conceptually close to these C patterns.
Explicit vs implicit this and readability
- Some developers dislike implicit
this; they prefer explicit object parameters for clarity about what is state vs local/global. - Others find mandatory
thisnoisy, especially in math-heavy code. Naming conventions (e.g.,foo_,mFoo) and optional explicitthisin C++/Java are seen as adequate by them.
Practicality, maintainability, and why use C
- Supporters like C’s minimalism: dynamic dispatch is always visible, no language-enforced OO “shape”, and you can pick exactly which functions go in which tables (including creative patterns like per-object vtables or trait-like tables).
- Critics report large C codebases using these patterns becoming hard to maintain: more boilerplate, weaker tool support, harder for newcomers. They recommend using C++ if you want pervasive OO.
- Others reply that when kept idiomatic and focused (as in the kernel), these patterns are powerful, efficient, and avoid C++’s complexity and compilation costs.