Difference between stack-allocated class and struct

Jonathan M Davis jmdavisProg at gmx.com
Mon May 2 14:03:16 PDT 2011


> What are the differences between class instantiated by scope and struct
> itself?
> Two, that comes to my mind are:
> - vtable existance (yep, struct with inheritation - that's what i like)
> - lol, i just forgot while writing this e-mail

First off, I would point out that scoped classes are going away (though 
std.typecons.scoped serves as a replacement).

Now, structs are value types and are meant to be on the stack. When you assign 
one to another, a copy is made. If the original is altered, it doesn't affect 
the copy, and if the original goes away, the copy is unaffected.

Classes are reference types and are meant to be on the heap. When you assign 
one to another, you're merely copying the reference. Both refer to the same 
object. No copy is made. So, when you alter one, you also alter the other. 
When one goes away, it doesn't affect the other, but if the underlying object 
went away, then they would both be screwed.

Normally, class objects don't go away until the garbage collector collects 
them, but if you use scope (or std.typecons.scoped), then the object is on the 
stack instead of the heap, and as soon as that scope goes away, so does the 
object, so if you have references to it elsewhere, they're invalid, but the 
program won't know that, and it'll try and use them anyway. It can lead to 
serious bugs. Scoped classes are inherently unsafe, which is why they're going 
away.

It's like when you return an address to a local variable:

int* foo()
{
    int a = 7;

    return &a;
}

The pointer will be invalid, and you're going to have bugs. Now, the 
compiler's going to catch such a simple case as this, but what if you did 
something like this?

int* foo()
{
    int a = 7;

    return bar(&a);
}

int* bar(int* b)
{
    return b;
}

The compiler can't catch that. The same goes if you were to use a scoped class 
instead of an int. In general, scoped classes are a _bad_ idea and should not 
be used unless profiling has shown that they speed up critical code and you're 
_certain_ that you're using them in a manner which won't cause a reference to 
the class to escape the function and outlive the function call.

As for everything else structs are structs and classes are classes. All of the 
normal differences apply. That includes the fact that structs have no 
inheritance and no vtable while classes do have inheritance and do have a 
vtable. However, you pretty much lose polymorphism if you use a scoped class. 
You're guaranteeing that the class that you're using is _exactly_ that type 
and not a subclass of that type. This is because the object is put on the 
stack inside the function and the compiler must know its _exact_ size. It's 
exactly like what you get with classes on the stack in C++. Putting them on 
the stack loses any of the advantages of polymorhism and risks slicing ( 
http://en.wikipedia.org/wiki/Object_slicing ) when you assign a subclass 
object to a base class object.

So, if you're using a scoped class, you're _not_ getting the benefits of 
polymorphism. What you're doing is saying that you know that you have an 
object of a particular type - that _exact_ type - which you know is not going 
to need to exist once you exit that scope, and you want to increase the 
efficiency of that code, so you make it so that the object is created on the 
stack instead of the heap. And in so doing, you _must_ make sure that no 
reference to that object escapes - which often isn't easy if you have to pass 
that object to any other functions, and even if you verify that it's safe now, 
it might not be later.

Structs and classes are inherently different. Structs are value types and 
classes are reference types. All you're doing with a scoped class is forcing 
the object to be put on the stack instead of the heap, which doesn't really 
change anything for the class except for the fact that it must be of that 
_exact_ type (so no polymorphism), and you have to make sure that no 
references to it escape, or you could have serious bugs.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list