On 14/11/2010 11:08, spir wrote:
Hello,


There seems to be 2 main differences between structs&  classes:
1. structs instances are direct values, implement value semantics;
> while class instances are referenced (actually "pointed")
2. classes can be subtyped/subclassed in a simple way; structs
> cannot be really subtyped -- but there is the "alias this" hack

I am trying to understand what should be the rationale behind choosing
> or the other form of structured type. Letting aside subtyping
> considerations,
meaning concentrating on the consequences of the first point above.

Here are my views on the topic:

* On the semantic side:
An element should be referenced when its meaning is of a "thing",
an entity that has an identity distinct from its value; a things
remains "itself" whatever its evolution in time; it can also be
multiply referenced. For instance, a visual form that can change
would be a thing.

An element should be a value type when it provides information
> about a thing; a value makes no sense by itself, it is bound to
what it describes an aspect of; referencing a value is meaningless,
only copy makes no sense. For instance, the position&
color of a visual form should be values.

One of the best descriptions of the differences I've seen so far.

* On the efficiency side:
Struct instances have fast creation, because allocated on the stack
> (*)? Class instances are costly to create. But then, passing
> class instances around is light, since only a reference is
> copied, while struct instances are copied at the field level.

Structs get allocated on the stack when used as local vars, they also get embedded in classes when they are members. i.e. if you add a 40 byte struct to a class, the class instance size goes up by ~40 bytes (depending on padding).

You can still new a Struct if needed and you can always use ref & plain pointers as well, so you can easily blur the line of Structs not having identity.

Struct's don't have a virtual table pointer or a monitor pointer, so they can be smaller than class instances.

You can also precisely control the content and layout of a struct, which you can't do with a class; so you'd have to use Structs when doing vertices in 3d programs that you want to pass to OpenGL/DirectX

Both of these points may conflict with semantic considerations above:
> we may want to use structs for fast creation, but if ever they mean
> "things", we must think at referencing them manually and/or using
> ref parameters. We may want to use classes for light passing,
> but if they mean values, we must either never assign them or
> manually copy their content. It's playing with fire: very
> dangerous risks of semantic breaks in both cases...

Perhaps, but they are tools to implement a program design;
it's the program design that should be driving your choices not abstract semantic considerations. Go down that route and you'll never get anything done.

Here is an example: a module implementating general-purpose tree/node structure.
Let us say there are both a Tree&  Node types -- the nodes do not implement
> global methods, only the tree does. So, a node just holds an element
> and a set of child nodes, possibly methods to manipulate these fields.
> A tree in addition has methods to traverse nodes, search,
> insert/remove, whatever...

What kinds should be Node&  Tree? Why? Are there sensible alternatives? If yes, 
what
> are the advantages and drawback of each? In what cases?
(questions, questions, questions...)

Well Tree would probably be a class as you are likely to be passing it around a lot and Node types would be structs.

For Node's you don't need inheritance, you want to keep their size as small as possible and they are not visible outside the context of the tree.

And on the other hand, you probably don't want virtual methods in your tree either, so you could make that a smart pointer type struct as well and then you've got a struct masquerading as a reference type...



Denis

(*) Is this true? And why is the stack more efficient than the heap?

You can allocate from the stack in amortised constant time; usually a very fast time. If you need 10 bytes of stack, you just subtract 10 from the stack pointer which is a single ASM instruction and as long as you don't hit the bottom of the stack you are done.

If you do hit the bottom of the stack (on windows/linux) you'll attempt to access none accessible memory; this will invoke the OS's memory manager.

If you've got enough free memory and free address space you'll be given a new stack page and things will continue, otherwise you'll get a stack overflow exception/seg fault.

Allocating new memory runs through D runtime and in principal may take an unbounded amount of time to find/allocate the size request. If you program has a very fragmented heap and you've loads of memory allocated it might take the allocator a very long time to determine it doesn't have any free memory and then finally go to the OS for more memory.


-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



--
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk

Reply via email to