www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Are D classes always garbage collected?

reply "Froglegs" <lugtug gmail.com> writes:
  From what I understand D classes are reference types, which 
would imply to me that they are either always garbage collected 
or rather less likely, reference counting.

Which is fine and all, but since structs don't support virtual 
functions, doesn't this pretty much force you to use classes and 
therefor GC if you want virtual functions?

So why don't structs support virtual funtions? I would like to 
have a type that is not GC'd or ref counted or any other 
nonsense, but supports virtual functions..

Am I missing something here? Thanks
Dec 21 2011
next sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thursday, 22 December 2011 at 02:29:10 UTC, Froglegs wrote:
 From what I understand D classes are reference types, which 
 would imply to me that they are either always garbage collected 
 or rather less likely, reference counting.

They are garbage-collected.
 Which is fine and all, but since structs don't support virtual 
 functions, doesn't this pretty much force you to use classes 
 and therefor GC if you want virtual functions?

You can allocate classes anywhere, if you're OK with forfeiting safety guarantees. For example, see emplace in std.conv: http://dlang.org/phobos/std_conv.html#emplace
 So why don't structs support virtual funtions? I would like to 
 have a type that is not GC'd or ref counted or any other 
 nonsense, but supports virtual functions..

Value type polymorphism has shown to be problematic. One notable problem is object slicing: http://en.wikipedia.org/wiki/Object_slicing
 Am I missing something here? Thanks

I *think* the language allows implementing something akin to value type polymorphism (sans syntax sugar), but currently the required compiler features (alias this, compile-time symbol/address evaluation) are not implemented well-enough to test my idea.
Dec 21 2011
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 12/21/2011 10:20 PM, Froglegs wrote:
 Which returned me a nice fat null pointer.. wth? Perhaps that should
 be a compile time error if you aren't supposed to use classes..

Strange... I'm not sure what the deal is with that overload. I meant the last one on the page (that takes a void[]).

Hum I've tried the array version but I believe it contains a rather serious bug... T emplace(T, Args...)(void[] chunk, Args args) if (is(T == class)) { enforce(chunk.length >= __traits(classInstanceSize, T), new ConvException("emplace: chunk size too small")); ... This fails whenever the size is greater or equal to the amount of memory required :(

That bug has recently been fixed: http://d.puremagic.com/issues/show_bug.cgi?id=6204
 Anyway I need the pointer version for what I was hoping to do, unless
 there is some way to convert a pointer into an array?

emplace() with classes is a little more involved compared to structs; I think because the type of the class variable need not be the same type as the instance.
 Is there any way to do something like this..

 void* pData = some_c_function();
 void [] fakeArray = pData, size;

Yes, as Andrew Wiley has shown: void[] fakeArray = pData[0..size]; Ali P.S. I have all of this in my Turkish book but that chapter hasn't been translated to English yet: http://ddili.org/ders/d/bellek_yonetimi.html
Dec 29 2011
prev sibling next sibling parent "Froglegs" <lugtug gmail.com> writes:
 You can allocate classes anywhere, if you're OK with forfeiting 
 safety guarantees. For example, see emplace in std.conv:

 http://dlang.org/phobos/std_conv.html#emplace

Ah thanks
 Value type polymorphism has shown to be problematic. One 
 notable problem is object slicing:

 http://en.wikipedia.org/wiki/Object_slicing

I see... seems like a pretty weak reason, I've never found that to be an issue in C++ as it is exactly what I'd expect to happen if I did something like that.
 I *think* the language allows implementing something akin to 
 value type polymorphism (sans syntax sugar), but currently the 
 required compiler features (alias this, compile-time 
 symbol/address evaluation) are not implemented well-enough to 
 test my idea.

Ah, faking it, hopefully that works out someday :)
Dec 21 2011
prev sibling next sibling parent "Froglegs" <lugtug gmail.com> writes:
 You can allocate classes anywhere, if you're OK with 
 forfeiting safety guarantees. For example, see emplace in 
 std.conv:

 http://dlang.org/phobos/std_conv.html#emplace


Hum calling emplace ending up calling this bit of code.. T* emplace(T)(T* chunk) if (is(T == class)) { *chunk = null; return chunk; } Which returned me a nice fat null pointer.. wth? Perhaps that should be a compile time error if you aren't supposed to use classes.. I tried placement new syntax but this tells me I need an allocator, whatever that means.. I swear D is google proof sigh
Dec 21 2011
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thursday, 22 December 2011 at 04:15:25 UTC, Froglegs wrote:
 You can allocate classes anywhere, if you're OK with 
 forfeiting safety guarantees. For example, see emplace in 
 std.conv:

 http://dlang.org/phobos/std_conv.html#emplace


Hum calling emplace ending up calling this bit of code.. T* emplace(T)(T* chunk) if (is(T == class)) { *chunk = null; return chunk; } Which returned me a nice fat null pointer.. wth? Perhaps that should be a compile time error if you aren't supposed to use classes..

Strange... I'm not sure what the deal is with that overload. I meant the last one on the page (that takes a void[]).
 I tried placement new syntax but this tells me I need an 
 allocator, whatever that means..

http://www.d-programming-language.org/memory.html#newdelete Note that this feature is on its way to be deprecated. emplace and clear are the future-proof method.
Dec 21 2011
prev sibling next sibling parent "Froglegs" <lugtug gmail.com> writes:
 Which returned me a nice fat null pointer.. wth? Perhaps that 
 should be a compile time error if you aren't supposed to use 
 classes..

Strange... I'm not sure what the deal is with that overload. I meant the last one on the page (that takes a void[]).

Hum I've tried the array version but I believe it contains a rather serious bug... T emplace(T, Args...)(void[] chunk, Args args) if (is(T == class)) { enforce(chunk.length >= __traits(classInstanceSize, T), new ConvException("emplace: chunk size too small")); ... This fails whenever the size is greater or equal to the amount of memory required :( Anyway I need the pointer version for what I was hoping to do, unless there is some way to convert a pointer into an array? Is there any way to do something like this.. void* pData = some_c_function(); void [] fakeArray = pData, size;
Dec 21 2011
prev sibling next sibling parent "Froglegs" <lugtug gmail.com> writes:
 T emplace(T, Args...)(void[] chunk, Args args) if (is(T == 
 class))
 {
   enforce(chunk.length >= __traits(classInstanceSize, T),
          new ConvException("emplace: chunk size too small"));
 ...

 This fails whenever the size is greater or equal to the amount 
 of memory required :(

Hum nevermind that, got confused by the IDE behavior. Anway this emplace function crashes when I call it with a very meaningless callstack.
Dec 21 2011
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thursday, 22 December 2011 at 06:43:33 UTC, Froglegs wrote:
 T emplace(T, Args...)(void[] chunk, Args args) if (is(T == 
 class))
 {
 enforce(chunk.length >= __traits(classInstanceSize, T),
        new ConvException("emplace: chunk size too small"));
 ...

 This fails whenever the size is greater or equal to the amount 
 of memory required :(

Hum nevermind that, got confused by the IDE behavior. Anway this emplace function crashes when I call it with a very meaningless callstack.

This works for me: import std.conv; class C { int i; this() { i = 42; } } unittest { void[__traits(classInstanceSize, C)] data = void; auto c = emplace!C(data[]); assert(c.i == 42); }
Dec 21 2011
prev sibling next sibling parent Andrew Wiley <wiley.andrew.j gmail.com> writes:
On Wed, Dec 21, 2011 at 10:20 PM, Froglegs <lugtug gmail.com> wrote:
 Which returned me a nice fat null pointer.. wth? Perhaps that should be=



 compile time error if you aren't supposed to use classes..

Strange... I'm not sure what the deal is with that overload. I meant the last one on the page (that takes a void[]).

Hum I've tried the array version but I believe it contains a rather serio=

 bug...

 T emplace(T, Args...)(void[] chunk, Args args) if (is(T =3D=3D class))
 {
 =A0 enforce(chunk.length >=3D __traits(classInstanceSize, T),
 =A0 =A0 =A0 =A0 =A0new ConvException("emplace: chunk size too small"));
 ...

 This fails whenever the size is greater or equal to the amount of memory
 required :(


 Anyway I need the pointer version for what I was hoping to do, unless the=

 is some way to convert a pointer into an array?

 Is there any way to do something like this..

 void* pData =3D some_c_function();
 void [] fakeArray =3D pData, size;

Yes: void* pData =3D some_c_function(); void[] fakeArray =3D pData[0..size]; Although Vladimir's solution is safer.
Dec 21 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 22 Dec 2011 00:01:53 -0500, Vladimir Panteleev  
<vladimir thecybershadow.net> wrote:

 On Thursday, 22 December 2011 at 04:15:25 UTC, Froglegs wrote:
 You can allocate classes anywhere, if you're OK with forfeiting  
 safety guarantees. For example, see emplace in std.conv:

 http://dlang.org/phobos/std_conv.html#emplace


Hum calling emplace ending up calling this bit of code.. T* emplace(T)(T* chunk) if (is(T == class)) { *chunk = null; return chunk; } Which returned me a nice fat null pointer.. wth? Perhaps that should be a compile time error if you aren't supposed to use classes..

Strange... I'm not sure what the deal is with that overload. I meant the last one on the page (that takes a void[]).

I see it, you are emplacing a class reference *pointer*, not a class reference. Just so you know, classes are references already, you don't need to use pointers. -Steve
Jan 07 2012