July 20, 2012
On Friday, 20 July 2012 at 21:41:45 UTC, Namespace wrote:
> Why comes "DTOR class" _after_ "end main" and not before?
> If i write "scope TestC c = ...;" it is correct, but i read that
> "scope" will be deprecated. Can someone explain me that behaviour?

The destructor will be invoked when the GC collects the object,
not when the last reference to it goes »out of scope«.

David
July 20, 2012
On Friday, 20 July 2012 at 21:51:02 UTC, David Nadlinger wrote:
> On Friday, 20 July 2012 at 21:41:45 UTC, Namespace wrote:
>> Why comes "DTOR class" _after_ "end main" and not before?
>> If i write "scope TestC c = ...;" it is correct, but i read that
>> "scope" will be deprecated. Can someone explain me that behaviour?
>
> The destructor will be invoked when the GC collects the object,
> not when the last reference to it goes »out of scope«.
>
> David

Really? Holy crap...
Can i correct this? And will "scope" for classes really
deprecated?
July 20, 2012
On Friday, 20 July 2012 at 21:41:45 UTC, Namespace wrote:
> Something else which is against classes: incorrect scope
> behaviour:
>
> [code]
> import std.stdio;
>
> class TestC {
> public:
> 	this() {
> 		writeln("CTOR class");
> 	}
>
> 	~this() {
> 		writeln("DTOR class");
> 	}
> }
>
> struct TestS {
> public:
> 	this(int i) {
> 		writeln("CTOR struct");
> 	}
>
> 	~this() {
> 		writeln("DTOR struct");
> 	}
> }
>
> void main() {
> 	{
> 		writeln("begin scope");
>
> 		TestC c  = new TestC();
> 		TestS s = TestS(42);
>
> 		writeln("end scope");
> 	}
>
> 	writeln("end main");
> }
> [/code]
>
> Prints
>
> begin scope
> CTOR class
> CTOR struct
> end scope
> DTOR struct
> end main
> DTOR class
>
> Why comes "DTOR class" _after_ "end main" and not before?
> If i write "scope TestC c = ...;" it is correct, but i read that
> "scope" will be deprecated. Can someone explain me that behaviour?

That happens because the destructor is being called when Garbage
collector is cleaning the memory used by the class instance.
July 20, 2012
On 07/20/2012 02:54 PM, Namespace wrote:
> On Friday, 20 July 2012 at 21:51:02 UTC, David Nadlinger wrote:
>> On Friday, 20 July 2012 at 21:41:45 UTC, Namespace wrote:
>>> Why comes "DTOR class" _after_ "end main" and not before?
>>> If i write "scope TestC c = ...;" it is correct, but i read that
>>> "scope" will be deprecated. Can someone explain me that behaviour?
>>
>> The destructor will be invoked when the GC collects the object,
>> not when the last reference to it goes »out of scope«.
>>
>> David
>
> Really? Holy crap...
> Can i correct this? And will "scope" for classes really
> deprecated?

The truth is, the destructor may not ever be called.

Yes scope is (will be?) deprecated and is replaced by std.typecons.scoped:

import std.typecons;
// ...
        auto c = scoped!TestC();


Prints:

begin scope
CTOR class
CTOR struct
end scope
DTOR struct
DTOR class
end main

Ali
July 20, 2012
On Friday, 20 July 2012 at 21:54:05 UTC, Namespace wrote:
> On Friday, 20 July 2012 at 21:51:02 UTC, David Nadlinger wrote:
>> On Friday, 20 July 2012 at 21:41:45 UTC, Namespace wrote:
>>> Why comes "DTOR class" _after_ "end main" and not before?
>>> If i write "scope TestC c = ...;" it is correct, but i read that
>>> "scope" will be deprecated. Can someone explain me that behaviour?
>>
>> The destructor will be invoked when the GC collects the object,
>> not when the last reference to it goes »out of scope«.
>>
>> David
>
> Really? Holy crap...
> Can i correct this? And will "scope" for classes really
> deprecated?

I suppose that you need this:
http://dlang.org/phobos/std_typecons.html#scoped

July 20, 2012
> That happens because the destructor is being called when Garbage
> collector is cleaning the memory used by the class instance.

How can i call the DTOR or at least a Release method after end of scope?
Optimally automatic without any explicit calls.
July 21, 2012
On Saturday, July 21, 2012 00:04:21 Namespace wrote:
> > That happens because the destructor is being called when Garbage collector is cleaning the memory used by the class instance.
> 
> How can i call the DTOR or at least a Release method after end of
> scope?
> Optimally automatic without any explicit calls.

You can use std.typecons.scoped, but then you can't pass the class around, which is exactly what would have happened with scoped. It's inherently unsafe.

You can do something like

MyObj obj = createObj();
scope(exit) clear(obj);

but again, it's going to be destroyed immediately when it leaves scope, and any reference to it which escapes will blow up when you use it. In neither case is there any reference counting.

You could use std.typecons.RefCounted, but unless _every_ instance of the object is wrapped in it (unfortunately, it uses alias this on its payload, making it easy to accidentally have references to its payload escape - which will be screwed up when the ref count reaches zero, and the payload is destroyed)

The reality of the matter is that if you want deterministic destruction, you should be using a struct, not a class. There are ways to force a class to be destroyed when it leaves scope, but they're inherently unsafe, so they should only be used if you really need them and know what you're doing. Classes are intended to live on the GC heap and be destroyed and freed by the GC when a garbage collection cycle finds that nothing refers to that object anymore.

- Jonathan M Davis
July 21, 2012
On Friday, 20 July 2012 at 16:02:18 UTC, Namespace wrote:
> If i @disable the postblit i get a strange behaviour:
>
> [code]
> struct Test {
> public:
> 	int _id;
>
> 	this(int i) {
> 		_id = i;
>
> 		writeln("CTOR");
> 	}
>
> 	@disable
> 	this(this);
>
> 	~this() {
> 		writeln("DTOR");
> 	}
> }
>
> void main() {
> 	Test[] _arr;
>
> 	_arr ~= Test(42);
>
> 	writeln(_arr[0]._id);
>
> 	writeln("end main");
> }
> [/code]
>
> prints:
>
> CTOR
> DTOR
> 42
> end main
>
> The DTor is called _before_ i write Test's id but i can still print the correct id.
> Implicit Copy CTor? ;)

Array appending and struct postblit behavior is now broken.
I've suggested a pull request to fix these bugs.

https://github.com/D-Programming-Language/dmd/pull/1037

Bye.

Kenji Hara
July 21, 2012
That's great. Hope 2.060 fixes many errors, especially in structs.
BTW: When comes 20060? I thought dmd versions come in cycles of 2-3 months?
July 21, 2012
On Saturday, July 21, 2012 22:18:40 Namespace wrote:
> That's great. Hope 2.060 fixes many errors, especially in structs. BTW: When comes 20060? I thought dmd versions come in cycles of 2-3 months?

Usually, they do, but Walter got caught up in working on COFF support for Windows and there's no sign of him looking to do a release before that's done. So, it could actually be a few months away. It probably would have been better to do a release _before_ adding all of the COFF support, but that doesn't seem to be happening. That's partially why that whole discussion on creating a D stable branch popped up in the main newsgroup, and there's now a side project created to do that as announced in the announce group (though, they intended to start with 2.060, so I don't know what they're going to do given the delay).

- Jonathan M Davis