Struct vs class - I am trying to understand why Rack seems to avoid classes

Looking into VCV Rack and developing modules, I have come across more structs than in the last 15 years combined. At least it feels like that. I can’t remember seing a single class. This being rather unusual for ‘modern’ code, I am wondering what might be the reason.

At first I thought that this had to be for performance reasons but then I read again and again that there is no difference regarding performance. Apparently, the only significant difference -according to what I have read- is the definition of default accessibility (struct: public, class: private).

Since I am under the impression that structs should be used for data structures (pure data, no functionality) and classes for object types (contain information i.e. data with a meaning defined within the class, have functionality), I am really curious about the reason for the approach used in Rack.

Could anybody please enlighten me? Thanks a lot!

3 Likes

Does make me nostalgic for the turbopascal/delphi days where record, object and class all had varying levels of overhead though. Since all objects type IDs were congregated at compile time it dispatched off that instead of vtables, which is faster (vtables have a ~20% slowdown, according to compiles benched with GCC flags to force all calls to pass through it.)

Yes, this is the only difference.

1 Like

I liked and used Delphi a lot, too, back in the days…

Thanks! One mystery solved :smile:

I never really understood the point of that, back (all those years ago). I wonder whether anyone will every replace c++?

I guess that is because you are supposed to directly access data in a struct from outside (assuming it has no functionality) while you should not access the data in a class (knows the meaning of the data -potentially better than the outside- and has functionality) directly from outside but rather through getters and setters. The reason is that you want to prevent the outside from (mis)using the content of a class without the class knowing it or having an opportunity to intervene/correct. This is known as encapsulation https://en.wikipedia.org/wiki/Encapsulation_(computer_programming).

Summary: Structs and classes are supposed to be used for different purposes.
Struct: Data structure, accessed from outside. The data structure has no knowledge about the meaning of its data and no functionality.
Class: Information (data + meaning) and functionality, accessed through method calls. The class knows best what to do with its information and helps you/prevents you from messing things up.

This is why you want struct members to be public and class members to be private by default.

The funny thing is: Both structs and classes can be used either way. I suppose this has to be for historical or compatibility reasons.

As far as I know using structs where classes should be used is usually discouraged. But nevertheless it works :slight_smile:

P.S.: I wonder what happens if you replace all occurrences of ‘struct’ in the Rack code by ‘class’. ideally nothing.

Because C.

C structs had no visibility protections, and C++ is eternally obsessed with keeping all of C’s fault’s going forward. So structs had to stay like C expected them to be, while C++'s own additions included the ability to set visibilities. If structs suddenly [edit: defaulted to] private members, all of the C code you interop with would break hard and C++ wouldn’t have gained market share as easily. (Although, that’s debatable, since C++'s competitors were often falling on their face demanding high license fees for unproven languages. For as many thigns as C++ did wrong for so long, letting people use it before the commercial compilers came along is one thing it did right.)

Breakages, probably.

According to Bjarne Stroustrup, the default visibility of struct was all about making it as easy as possible for people to move their C projects to C++.

Continuing to provide struct, and with its default public visibility meant that there was no need to change any structs to classes, or to add any public specifiers in order to get your code to compile.

So it was more than just backwards compatibility.

(I’m taking this from his comments in the 4th edition of ‘The C++ Programming Language’)

I forgot to answer the OP’s question. Rack uses struct because it doesn’t use in-class encapsulation, and it saves the one public: line.

1 Like