Hacker News new | ask | show | jobs
by mistrial9 1755 days ago
I think this approach is working too hard to realize Virtual Tables and Virtual Pointers. Another, different implementation is to define an array of function pointers, one function per method implemented, and then extend the array per subclass; each child class fills in its own or parents function pointers at init time.
3 comments

Not an array, a struct is ok, and in C99 style it is very well readable.

For example Linux Kernel style is:

  static const struct file_operations fops = {
        .open    = my_open,
        .release = my_release,
        .read    = my_read,
        .write   = my_write
  };
that's all, very straightforward. Also there is no need to prefix the function name with &
PP (parent post) here - yes, several variations available in C99; I haven't tried to retrieve my examples yet. (I used this commercially in the 90s)
This pattern goes back to pre-Version-7 UNIX kernels, with only minor syntactic updates. That it long predates OO demonstrates it is not OO. That does not make it any less effective, or less useful.
It does not predate OO.

The first OO language, SIMULA-67 became public knowledge before the start of even the PDP-7 UNIX, which is extremely unlikely to have used such a pattern, which probably appeared only when UNIX was rewritten in C, starting in 1973.

Even Smalltalk-72 predated the C-version of UNIX.

However, it is likely that this pattern was chosen in UNIX independently of the previous OO languages.

Also what many usually forget, C++ was also born on the same building as UNIX.

Hence why C++ got so fast adopted across UNIXes and C compiler vendors on other platforms.

That was not the reason.

But it was the reason that C, as standardized, adopted several C++ innovations first.

It was definitly the reason, by 1992 it was impossible to buy a C compiler that also did not had a C++ one in the box.

Also why Apple moved from Object Pascal to C++ on MPW.

To a great extent, the difference between "a data structure plus a dispatch table" and "an object" is primarily in how you squint.

It's certainly a form of polymorphism.

It's a measurable difference. OO in C++ must use double indirect vtable method calls, whilst this OO in C uses only one indirection. It's measurably faster. Objects are a bit larger though, cloning is a bit more expensive, but method calls are much faster and much easier to cache.
I think you're misinterpreting GP's code. It is a vtable, hence the static const. There would be a pointer in each struct "instance" to this static vtable, thus the same double indirection would occcur as in C++.
Plus this was a discussion about conceptual models and "what counts as OO", not the specific details and optimisation possibilities of the implementation.
OP mimic'd C++ vtables. But in C you can do better and inline them. I mostly inline them for performance reasons.
> That it long predates OO demonstrates it is not OO.

This does not make any sense. People did not wait until someone gave a name to the rule-of-three to use it, and that does not make these uses any less rule-of-three than the ones that occured post-naming.

Or perhaps go the more novel way of Piumarta's and Warth's Open, extensible object models? http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.121...
What would also be helpful is a standard way to declare to the compiler that it should or should not optimize each flagged polymorphic late bound call implementation to be early bound; moving the calls into separate or merged files during linking is not an in context solution.
not really important, retrieval of a function pointer at a known slot, and then calling that function pointer, can be really fast on a lot of arch.