Live data from Hacker News

OOP in C

staff.washington.edu

31–40 of 149 posts

Re: OOP in C

#31

[flagged]

All you need is a field in the struct to point to your vtable. Please try to think more charitably and not be so aggressive. Even if the author was wrong, which they aren't, doesn't mean they don't have the kernel of a good idea.

Charitability is not a tool merely for being nice to others, but being nice to yourself. You learn more this way.

Re: OOP in C

#32
post #21
post #16

Earlier quoted context omitted.

Polymorphism in C is trivial: You use a vtable - a struct of method pointers. Same approach most languages with "simple" method resolution mechanisms, like e.g C++, uses under the hood. You don't need macros. You either call via the vtable, or you write a wrapper per interface per message. E.g. struct class { void (*vtable[NUM_SLOTS]); }; struct object { struct class * class; }; typedef struct object object; const in…

what does an "object" look like? how do i derive from it?

Easy; a subclass struct embeds the superclass struct as its first member.

Simple example here: https://embeddedgurus.com/state-space/2008/01/object-based-p...

Lots more here: https://stackoverflow.com/questions/351733/how-would-one-wri...

Re: OOP in C

#33
post #12

C required the simplest form of OOP, but who standardizes it decided to deny the feature to the language: the ability to have callable structure methods (function pointers) with explicit "self" pointer. Not even constructors/destructors. After all it's C, and you can write list->init() and list->free(). This simple form to bind data and the functions operating on such data would make many codebases better.

That wouldn't actually help much. In the case that there is no inheritance, using a function pointer has unnecessary overhead (pointer storage, indirect call, additional parameter). In the case of inheritance, the pointer type differs and thus the function pointer type wouldn't be compatible either.

Re: OOP in C

#34
post #30

Earlier quoted context omitted.

Nothing in your example looks or reads as trivial . That is a gross perversion of a simple procedural language.

Trivial to a C developer then. This has been typical of C code for literally decades. The only thing that sucks there is writing wrappers, but it's easy to generate them. From a user point of view you end up doing things like: string * str = string_new(); int len = string_length(str); So it looks just like most other typical C code using prefixes per interface and passing pointers to structs around. In practice, like…

"int string_length(void * self) { return ((int ()(void ))((object *)self)->class->vtable[STRING_LENGTH_SLOT])(self);"

Oh.My.God.

At this point, you might as well be using Java.

Re: OOP in C

#35
post #12

C required the simplest form of OOP, but who standardizes it decided to deny the feature to the language: the ability to have callable structure methods (function pointers) with explicit "self" pointer. Not even constructors/destructors. After all it's C, and you can write list->init() and list->free(). This simple form to bind data and the functions operating on such data would make many codebases better.

That wouldn't actually help much. In the case that there is no inheritance, using a function pointer has unnecessary overhead (pointer storage, indirect call, additional parameter). In the case of inheritance, the pointer type differs and thus the function pointer type wouldn't be compatible either.

You need to use a void* self pointer. And indirect through the vtable in all calls to virtual methods, even those that are part of the object itself. Thus, e.g. a method defined on a base class might end up calling an implementation deep in the inheritance hierarchy, that didn't even exist when the base class code was written. There's no real equivalent to this when doing simple interface inheritance, but it's very much part of the actual semantics here.

Re: OOP in C

#36
post #30

Earlier quoted context omitted.

Trivial to a C developer then. This has been typical of C code for literally decades. The only thing that sucks there is writing wrappers, but it's easy to generate them. From a user point of view you end up doing things like: string * str = string_new(); int len = string_length(str); So it looks just like most other typical C code using prefixes per interface and passing pointers to structs around. In practice, like…

"int string_length(void * self) { return ((int ( )(void ))((object *)self)->class->vtable[STRING_LENGTH_SLOT])(self);" Oh.My.God. At this point, you might as well be using Java.

You are just being glib here.

If you want simpler models see my other comments in this thread.

Re: OOP in C

#37
post #30

Earlier quoted context omitted.

Trivial to a C developer then. This has been typical of C code for literally decades. The only thing that sucks there is writing wrappers, but it's easy to generate them. From a user point of view you end up doing things like: string * str = string_new(); int len = string_length(str); So it looks just like most other typical C code using prefixes per interface and passing pointers to structs around. In practice, like…

"int string_length(void * self) { return ((int ( )(void ))((object *)self)->class->vtable[STRING_LENGTH_SLOT])(self);" Oh.My.God. At this point, you might as well be using Java.

If you're writing C, you'll be writing much worse than that on a regular basis. There's a reason I rarely use C any more.

But of course if you're going to reimplement OO from scratch in C you will see the entire machinery laid bare. You're only doing it in the first place either because you're committed to using C for whatever reason, or to understand OO implementation strategies.

Re: OOP in C

#38
I think arrays of 64 byte structures is the most optimal way to architect your multicore "on the same memory" code.

Preferably using int/float which should be atomic on X86 and hopefully on modern ARM too, don't know about RISC-V yet.

Re: OOP in C

#39

[flagged]

Agree. What the author did here is just plain data types, not even abstract data types. Another big mistake in the article is

>Classes in an object oriented design are fundamentally ADTs

It isn't. I would suggest the paper Object-Oriented Programming Versus Abstract Data Types by William R. Cook which explains the fundamental differences between the two data abstraction techniques.

edit:

https://www.cs.utexas.edu/users/wcook/papers/OOPvsADT/CookOO...

Re: OOP in C

#40
post #12

C required the simplest form of OOP, but who standardizes it decided to deny the feature to the language: the ability to have callable structure methods (function pointers) with explicit "self" pointer. Not even constructors/destructors. After all it's C, and you can write list->init() and list->free(). This simple form to bind data and the functions operating on such data would make many codebases better.

That wouldn't actually help much. In the case that there is no inheritance, using a function pointer has unnecessary overhead (pointer storage, indirect call, additional parameter). In the case of inheritance, the pointer type differs and thus the function pointer type wouldn't be compatible either.

Inheritance is nowadays almost considered a bad practice, in fact newer languages, such as Rust, doesn't support it, and in languages that has it (Java, C#, etc) nowadays they always tell you to prefer composition over inheritance.

> using a function pointer has unnecessary overhead

This is true, it's inefficient. But for a lot of application, also irrelevant at performance level, and would provide a good abstraction.

Post reply on HN