December 19, 2010
Andrej Mitrovic:

> Is this another bug?:

I don't exactly know what's going on, but I have added a modified version of your code to the issue 5115.

Bye,
bearophile
December 19, 2010
On Mon, 20 Dec 2010 07:00:31 -0800
David Currie <curriedr@iinet.net.au> wrote:

> Can a class be instantiated on the stack ?

Yes, check std.conv.emplace http://www.digitalmars.com/d/2.0/phobos/std_conv.html#emplace and alloca() I don't know details about interaction of such objects with GC though.

Also there is scarcely documented storage class scope, which for class objects means that they will be destroyed upon scope exit, but also currently results in that object itself will be placed on the stack, no memory in heap is allocated.

>    C myC(3);  // C++ syntax BUT is there a d equivalent
> It appears that D ASSUMES myC is really a myC*(in C++)

Not exactly. All class objects have reference semantic, so when you declare variable of type C you really declare a reference. The reference is what you get from new, pass as parameters, etc.

> Will a struct do?

structs on the contrary have value semantic, so when you declare struct variable you get the memory for struct allocated on stack or in data segment. When you pass or return structs -- you return or pass value, that is a copy of data.

You may be also interested in the way dynamic arrays are handled, as arrays are value type, yet they hold a pointer to memory. This means that passing them as parameter or returning them does copy pointer and length, but actual data is stil shared until you do something which will force D to relocate it. All kind of not obvious implications here.

> Does a struct have a constructor (as opposed to an opcall?)

Yes, and more. http://www.digitalmars.com/d/2.0/struct.html

-- 
Nick Voronin <elfy.nv@gmail.com>
December 19, 2010
On Monday 20 December 2010 07:00:31 David Currie wrote:
> I am new to D (like many have done C++ , Java ).
> 
> Can a class be instantiated on the stack ?
> 
> eg
> 
> class C
> {
>    private  int _I1;
>    private  int _I2;
> 
>    public:
> 
>    this(int pI) // constructor
>    {
>      _I1 = pI;
>      _I2 = pI + 1;
>    }
> 
> // ...  other methods etc
> }
> 
> void f()  // just a function
> {
> 
>    C myC(3);  // C++ syntax BUT is there a d equivalent
> 
> }
> 
> It appears that D ASSUMES myC is really a myC*(in C++)
> 
> and therefore requires
> 
> C myC = new C(3);
> // but this ALWAYS requires calling the memory allocator
> // this is what Java does (forces your Class instance onto the Heap)
> 
> Is there any way in D to instantiate a stack object ?
> 
> Will a struct do?

Structs are value types. Therefore, they go on the stack unless you have a pointer to them.

struct Foo {}

Foo a;  //on stack
Foo* b = new Foo(); //on heap


Classes are reference types. The are therefore always on the heap. It's like what you get in Java.

class Bar {}

Bar a;  //On the heap.


Structs do not have inheritance (and thus don't have polymorphism), but they can be used for RAII. Assigning one to another means copying it (or moving it if the compiler determines that it can). Because struct member functions are not virtual, they often can be inlined.

Classes do have inheritance (and thus do have polymorphism), but they can't use RAII. Assigning one to another means assigning a reference. Both references now refer to the same object. You'll have to use a clone method of some kind to get an actualy, deep copy. Because class member functions are almost always virtual, it's much rarer that they can be inlined.

The language did have scoped classes, which put the class itself on the stack instead of the heap:

class Bar {}

scope Bar a; //On the stack.


But it's inherently unsafe, so it's being removed from the language. There will be a library solution to do it, but again, it's unsafe. If you were to pass a scaped class to any other function, you risk the reference escaping, and then you'll end up with a reference to an object that doesn't exist once the function that declared it exits.

Classes are meant to be on the heap. structs are meant to be on the stack but can be on the heap. Generally-speaking, if you use a class if you need a reference type or need polymorphism. Otherwise, you use a struct (reasons for using one or the other can, of course, get more complicated that that, but that's the core of it).

Allowing classes on the like C++ does allows for problems like sheering and disallows polymorphism. D opted to split the concept into two different types of types: classes and structs.

The language which is closest to D with regards to structs and classes that I'm aware of is C#, though I believe that D structs are definitely more powerful than C# structs. In D, you just don't use classes as often as you'd do in Java or C++, because structs in D do a lot of what classes do in those languages. For any user-defined type, you need to decide whether a struct or a class is more appropriate for what you're trying to do. The approach has definite benefits, but it does take some getting used to.

> Does a struct have a constructor (as opposed to an opcall?)

structs can have constructs just like classes - they just can't have default constructors. The reason for this is that all types in D have an init property that variables of that type are initialized to when they are default initialized. For integral types, it's 0; for bool, it's false; for references and pointers it's null; etc. For structs, it's what the member variables are directly initialized to. init precludes having an arbitrary constructor, because init must be determinable at compile time, can't have exceptions being thrown, etc. We may get some sort of limited default constructor for structs at some point, but it's not at all straightforward to have one, so we don't. The solution then, if you need one, is to use a static opCall() function, and then do

Foo a = Foo(); //calls static opCall().

instead of

Foo a;  //Just uses Foo.init.


So, structs _do_ have constructors, just not default constructors.

- Jonathan M Davis
December 19, 2010
On Sunday 19 December 2010 13:23:42 Jonathan M Davis wrote:
> On Monday 20 December 2010 07:00:31 David Currie wrote:
> > I am new to D (like many have done C++ , Java ).
> > 
> > Can a class be instantiated on the stack ?
> > 
> > eg
> > 
> > class C
> > {
> > 
> >    private  int _I1;
> >    private  int _I2;
> > 
> >    public:
> > 
> >    this(int pI) // constructor
> >    {
> > 
> >      _I1 = pI;
> >      _I2 = pI + 1;
> > 
> >    }
> > 
> > // ...  other methods etc
> > }
> > 
> > void f()  // just a function
> > {
> > 
> >    C myC(3);  // C++ syntax BUT is there a d equivalent
> > 
> > }
> > 
> > It appears that D ASSUMES myC is really a myC*(in C++)
> > 
> > and therefore requires
> > 
> > C myC = new C(3);
> > // but this ALWAYS requires calling the memory allocator
> > // this is what Java does (forces your Class instance onto the Heap)
> > 
> > Is there any way in D to instantiate a stack object ?
> > 
> > Will a struct do?
> 
> Structs are value types. Therefore, they go on the stack unless you have a pointer to them.
> 
> struct Foo {}
> 
> Foo a;  //on stack
> Foo* b = new Foo(); //on heap
> 
> 
> Classes are reference types. The are therefore always on the heap. It's like what you get in Java.
> 
> class Bar {}
> 
> Bar a;  //On the heap.
> 
> 
> Structs do not have inheritance (and thus don't have polymorphism), but they can be used for RAII. Assigning one to another means copying it (or moving it if the compiler determines that it can). Because struct member functions are not virtual, they often can be inlined.
> 
> Classes do have inheritance (and thus do have polymorphism), but they can't use RAII. Assigning one to another means assigning a reference. Both references now refer to the same object. You'll have to use a clone method of some kind to get an actualy, deep copy. Because class member functions are almost always virtual, it's much rarer that they can be inlined.
> 
> The language did have scoped classes, which put the class itself on the stack instead of the heap:
> 
> class Bar {}
> 
> scope Bar a; //On the stack.
> 
> 
> But it's inherently unsafe, so it's being removed from the language. There will be a library solution to do it, but again, it's unsafe. If you were to pass a scaped class to any other function, you risk the reference escaping, and then you'll end up with a reference to an object that doesn't exist once the function that declared it exits.
> 
> Classes are meant to be on the heap. structs are meant to be on the stack but can be on the heap. Generally-speaking, if you use a class if you need a reference type or need polymorphism. Otherwise, you use a struct (reasons for using one or the other can, of course, get more complicated that that, but that's the core of it).
> 
> Allowing classes on the like C++ does allows for problems like sheering and disallows polymorphism. D opted to split the concept into two different types of types: classes and structs.
> 
> The language which is closest to D with regards to structs and classes that I'm aware of is C#, though I believe that D structs are definitely more powerful than C# structs. In D, you just don't use classes as often as you'd do in Java or C++, because structs in D do a lot of what classes do in those languages. For any user-defined type, you need to decide whether a struct or a class is more appropriate for what you're trying to do. The approach has definite benefits, but it does take some getting used to.
> 
> > Does a struct have a constructor (as opposed to an opcall?)
> 
> structs can have constructs just like classes - they just can't have default constructors. The reason for this is that all types in D have an init property that variables of that type are initialized to when they are default initialized. For integral types, it's 0; for bool, it's false; for references and pointers it's null; etc. For structs, it's what the member variables are directly initialized to. init precludes having an arbitrary constructor, because init must be determinable at compile time, can't have exceptions being thrown, etc. We may get some sort of limited default constructor for structs at some point, but it's not at all straightforward to have one, so we don't. The solution then, if you need one, is to use a static opCall() function, and then do
> 
> Foo a = Foo(); //calls static opCall().
> 
> instead of
> 
> Foo a;  //Just uses Foo.init.
> 
> 
> So, structs _do_ have constructors, just not default constructors.

I should probably add that structs can have reference semantics as well if they have pointers or references internally, and they don't have a postblit constructor or, it doesn't do a deep copy (a postblit constructor - this(this) - being the constructor which runs after a struct has been memcpy-ed by the compiler, since the default copying of a struct uses memcpy). structs are generally value types, however, and classes are always reference types.

- Jonathan M Davis
1 2
Next ›   Last »