www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: structs vs classes

reply Jim <bitcirkel yahoo.com> writes:
biozic Wrote:

 Le 29/01/11 14:43, Jim a écrit :
 I'm a bit troubled with the class/struct dichotomy. I would prefer them both
to use the same keyword. Heap/stack allocation could be specified during
instantiation instead. Why? Now you need to choose one over the other. Not even
C++ has this limitation.

 Think about containers for example, should they be classes or structs? Do you
want them on the stack or on the heap?

 I guess it's possible to define the entire container as a mixin now. That
would let you have both heap and stack containers share definition, but
generally I think that the dichotomy should be abolished.

The difference between class and struct in D is more than heap or stack allocation. Having a common keyword for them would unwisely mask their fundamental differences (inheritance/polymorphism, reference/value semantics, etc.). Perhaps the suggestion is in fact one that has already been made but for which I can't remember the conclusion: how about abandoning 'new' in favor of more specific keywords/library templates that control whether the instantiation occur on the heap or on the stack?

Yes, abandoning new if it would help. Objects on the heap could be managed by different garbage collectors (or with different settings, mark-sweep, precise/conservative, reference-counting, etc.). I don't want to have to change the definition of the type. The instantiation is a separate concern to the implementation. It should be up to the user of a type to decide whether to allocate it on the stack or the heap and so on. The compiler should be intelligent enough to see whether the class is derived or not and do its optmisations accordingly.
Jan 29 2011
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday 29 January 2011 07:11:41 Jim wrote:
 biozic Wrote:
 Le 29/01/11 14:43, Jim a =C3=A9crit :
 I'm a bit troubled with the class/struct dichotomy. I would prefer th=



 both to use the same keyword. Heap/stack allocation could be specified
 during instantiation instead. Why? Now you need to choose one over the
 other. Not even C++ has this limitation.
=20
 Think about containers for example, should they be classes or structs?
 Do you want them on the stack or on the heap?
=20
 I guess it's possible to define the entire container as a mixin now.
 That would let you have both heap and stack containers share
 definition, but generally I think that the dichotomy should be
 abolished.

The difference between class and struct in D is more than heap or stack allocation. Having a common keyword for them would unwisely mask their fundamental differences (inheritance/polymorphism, reference/value semantics, etc.). =20 Perhaps the suggestion is in fact one that has already been made but for which I can't remember the conclusion: how about abandoning 'new' in favor of more specific keywords/library templates that control whether the instantiation occur on the heap or on the stack?

Yes, abandoning new if it would help. Objects on the heap could be managed by different garbage collectors (or with different settings, mark-sweep, precise/conservative, reference-counting, etc.). =20 I don't want to have to change the definition of the type. The instantiation is a separate concern to the implementation. It should be up to the user of a type to decide whether to allocate it on the stack or the heap and so on. =20 The compiler should be intelligent enough to see whether the class is derived or not and do its optmisations accordingly.

structs are value types. classes are reference types. That can drastically= =20 change how they are designed and used. Passing something to void func(A a) {/*...*/} is going to have _vastly_ different behavior when dealing with value types = than=20 when dealing with reference types. For a value type, it'll be a copy. For a= =20 reference type, it's just copying the reference, so the function is free to= =20 change the state of the object that you passed in. How on earth would the=20 compiler decide which behavior is correct? It can't. That's up to the=20 programmer. The differences between structs and classes are critical. It's _not_ just a= =20 question of optimization. And the compiler can't generally make an optimiza= tion=20 choice based on whether a type is derived or not anyway, because it also ne= eds=20 to know whether a type is derivide from _it_, and it can't know that at com= pile=20 time thanks to the separate compilation model. Classes don't know about wha= t=20 types are derived from them, and the derived types could be in entirely sep= arate=20 libraries - separate shared libraries even (assuming that shared libraries = are=20 properly supported, which is on the TODO list). C# also chose to make structs and classes separate. It's a solide design=20 decision. In many, many cases, how a classes is designed and functions is=20 affected by how it is instantiated. It can make a big difference whether a = type is=20 intended to be instantiated on the stack or on the heap. structs are value types without inheritance or polymorphism. They support R= AII. classes are reference types with inheritance and polymorphism. They don't r= eally=20 support RAII (they have destructors, but there's no guarantee that they'll = ever=20 be called, and there are various limitation on their destructors). They are distinctly different. It was a mistake for C++ to have polymorphic= types=20 which could go on the stack. It causes slicing and ultimately doesn't make= =20 sense. If you program in C++, you learn to deal with it and program in a wa= y=20 that it doesn't cause problems, but it's still a problematic design choice.= =20 Separating user-defined value and reference types makes things considerably= =20 cleaner and safer. C# did and and D does it. Java didn't do it, but that's= =20 because it doesn't _have_ user-defined value types. C++ is the only languag= e that=20 I know of which tries to conflate user-defined value and reference types. It may take some getting used to, but D's choice of separating structs and= =20 classes is a solid one. =2D Jonathan M davis
Jan 29 2011