Why are structs and classes so different?

Ola Fosheim Grøstad ola.fosheim.grostad at gmail.com
Mon May 16 16:47:29 UTC 2022


On Monday, 16 May 2022 at 15:18:11 UTC, Kevin Bailey wrote:
> I would say that assignment isn't any more or less of an issue, 
> as long as you pass by reference:

What I mean is if you write your code for the superclass, and 
later add a subclass with some invariants that depends on the 
superclass fields… then upcast an instance of the subclass to the 
superclass and pass it on… your risk the same issue. The subclass 
invariant can be broken because of sloppy modelling.

The premise for "slicing" being an issue is that people who write 
functions have no clue about how the type system works or how to 
properly model. So it is a lot of fuzz over nothing, because with 
that assumption you can make the exact same argument for 
references. (I've never had any practical issues related to 
"slicing", ever…)

Besides, slicing can very well be exactly what you want, e.g. if 
you have a super-class "EntityID" and want to build an array of 
all the EntityIDs… nothing wrong about slicing out the EntityID 
for all subclass instances when building that array.

Now, there are many other issues with C++, mostly related to the 
fact that they give very high priority to avoid overhead. E.g. 
take a new feature like std::span, if you create a subspan 
("slice" in D terminology) and the original span does not contain 
enough elements then C++ regards that as undefined behaviour and 
will happily return a span into arbitrary memory past the end of 
the original span. C++ is very unforgiving in comparison to 
"higher level" languages like D.

If we extend this reasoning to D classes, one can say that D 
classes are convenience constructs that does not pay as much 
attention to overhead. One example of this is how interfaces are 
implemented, each interface will take a full pointer in every 
instance of the class. The monitor mutex is another example. And 
how pointers to classes are different (simpler syntax) than 
pointers to struct also suggests that classes are designed more 
for convenience than principles.

Whether this is good or bad probably depends on the user group:

1. Those that are primarily interested in low level with a bit of 
high level might think it is "too much" and favour structs.

2. Those that are primarily interested in high level with a bit 
of low level might think otherwise.

In C++ everyone belong to group 1. In other system languages such 
as D and Rust you probably have a large silent majority in group 
2. (All those programmers that find C++ to be too brittle or hard 
to get into, but want comparable performance.)










More information about the Digitalmars-d-learn mailing list