July 22, 2012
A other question:
How can i check if t is valid, after i call "clear"?

[code]
import std.stdio;

class Test {
public:
	this() {
		writeln("CTor");
	}

	~this() {
		writeln("DTor");
	}
}

void main() {
	Test t = new Test();

	clear(t);

	writeln("end main");
}
[/code]

If i write assert(t !is null); it fails, and if i write
writeln(t); or assert(t); i get an access violation.
July 22, 2012
On 07/22/2012 09:27 AM, Mafi wrote:

>> Unfortunately it has a bad name, which is going to be changed.

> Really? I thought we have to stay with this name now. In my
> opinion this name is quite bad, especially in the presence of
> UFCS. What is going to be changed to? destroy()?

Yep! :) It should be available in 2.060:

// Scheduled for deprecation in December 2012.
// Please use destroy instead of clear.

https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L682

Ali

July 22, 2012
On Sunday, 22 July 2012 at 17:41:33 UTC, Ali Çehreli wrote:
> On 07/22/2012 09:27 AM, Mafi wrote:
>
> >> Unfortunately it has a bad name, which is going to be
> changed.
>
> > Really? I thought we have to stay with this name now. In my
> > opinion this name is quite bad, especially in the presence of
> > UFCS. What is going to be changed to? destroy()?
>
> Yep! :) It should be available in 2.060:
>
> // Scheduled for deprecation in December 2012.
> // Please use destroy instead of clear.
>
> https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L682
>
> Ali

And how do I check if my object is still valid?
July 22, 2012
On 07/22/2012 09:35 AM, Namespace wrote:
> A other question:
> How can i check if t is valid, after i call "clear"?

After the destructor is run, the object itself is put into a strange state. I amnot really sure about the actual details but I think the virtual function table is cleared (or perhaps just the destructor's entry?) so that the destructor is not going to be run again by the GC later.

Regarding the references to it, like 't' below, clear() cannot know about all of the references to the object. It could null the reference that is passed to it but apparently it doesn't do that maybe because null'ing one reference out of many wouldn't buy much.

Of course it is always possible to set it to null explicitly after calling clear():

 clear(t);
 t = null;

Because now we know that we shouldn't be using the local reference.

Ali

July 22, 2012
On Sunday, July 22, 2012 20:14:20 Namespace wrote:
> On Sunday, 22 July 2012 at 17:41:33 UTC, Ali Çehreli wrote:
> > On 07/22/2012 09:27 AM, Mafi wrote:
> > >> Unfortunately it has a bad name, which is going to be
> > 
> > changed.
> > 
> > > Really? I thought we have to stay with this name now. In my opinion this name is quite bad, especially in the presence of UFCS. What is going to be changed to? destroy()?
> > 
> > Yep! :) It should be available in 2.060:
> > 
> > // Scheduled for deprecation in December 2012.
> > // Please use destroy instead of clear.
> > 
> > https://github.com/D-Programming-Language/druntime/blob/master/src/object. di#L682
> > 
> > Ali
> 
> And how do I check if my object is still valid?

You don't. The object is completely invalid at that point. Its vtbl has been zeroed out. Asking how you check whether it's valid is like asking how you can tell whether an object in C++ which has been deleted is valid. It just doesn't work that way. If you're destroying it, you need to then _never_ use it for _anything_. You can set a reference which pointed to it to null, and then it's null, and you can check for null, but an object which has had clear/destroy called on it is in an invalid state and should not be touched. It's specifically set up such that it's highly likely to cause your program to crash if you try and use it at all. If you want to check an object for validity, you need to do something else.

- Jonathan M Davis
July 22, 2012
On Sunday, 22 July 2012 at 18:14:21 UTC, Namespace wrote:
> On Sunday, 22 July 2012 at 17:41:33 UTC, Ali Çehreli wrote:
>> On 07/22/2012 09:27 AM, Mafi wrote:
>>
>> >> Unfortunately it has a bad name, which is going to be
>> changed.
>>
>> > Really? I thought we have to stay with this name now. In my
>> > opinion this name is quite bad, especially in the presence of
>> > UFCS. What is going to be changed to? destroy()?
>>
>> Yep! :) It should be available in 2.060:
>>
>> // Scheduled for deprecation in December 2012.
>> // Please use destroy instead of clear.
>>
>> https://github.com/D-Programming-Language/druntime/blob/master/src/object.di#L682
>>
>> Ali
>
> And how do I check if my object is still valid?

AFAIK, there are no invalid objects in D*. structs don't have default constructors, because they all have a compile time "init" value which they are filled with when "emptied"/"moved"/"cleared". Ergo, even after being "destroyed", they are still valid.

Arrays are set to a null slice.

Pointers and class references are set to null.

To check a class reference, then "if(instance is null)" should do what you want BTW.

*Provided you don't go out of your way to give them an invalid state, of course.
July 22, 2012
Works fine. :)
Now my little test case work as expected:

[code]
import std.stdio;

class Test {
public:
	this() {
		writeln("CTor");
	}

	~this() {
		writeln("DTor");
	}

	void echo() const {
		writeln("Here is Test");
	}
}

struct scoped {
private:
	Test* _t;

public:
	this(ref Test t) {
		this._t = &t;

		writeln(" >> scoped CTor");
	}

	@disable
	this(this);

	ref scoped opAssign(ref Test t) {
		this.Release();

		this._t = &t;

		writeln(" >> scoped Assign");

		return this;
	}

	~this() {
		writeln(" >> scoped DTor");
		this.Release();
	}

	void Release() {
		if (this._t !is null && *this._t !is null) {
			writeln("Clear scoped content");

			clear(*this._t);
			*this._t = null;
			this._t = null;
		}
	}

	@property
	Test* Value() {
		return this._t;
	}

	alias Value this;
}

class Bar {
private:
	scoped _sc;

public:
	this(ref Test f) {
		writeln("begin this");
		this._sc = f;
		writeln("end this");
	}

	~this() {
		writeln("DTOR BAR");
	}
}

void main() {
	Test t = new Test();

	clear(t);

	Test t2 = new Test();

	{
		scoped s = t2;
		s.echo();

		writeln("end scope");
	}

	assert(t2 is null);

	Test t3 = new Test();
	Bar b = new Bar(t3);

	assert(t3 !is null);

	writeln("end main");
}
[/code]
July 22, 2012
On Sunday, July 22, 2012 20:45:05 monarch_dodra wrote:
> AFAIK, there are no invalid objects in D*. structs don't have default constructors, because they all have a compile time "init" value which they are filled with when "emptied"/"moved"/"cleared". Ergo, even after being "destroyed", they are still valid.
> 
> Arrays are set to a null slice.
> 
> Pointers and class references are set to null.
> 
> To check a class reference, then "if(instance is null)" should do
> what you want BTW.
> 
> *Provided you don't go out of your way to give them an invalid state, of course.

Nothing in D is in an invalid state as long as you place nice, but it's perfectly possible to put an object in an invalid state if you try.

int i = void;

will make i garbage. It avoids the initialization and is therefore an optimization technique, but by using it, you do get a variable which is an an invalid state.

Calling clear on a class object puts it in an invalid state. It calls its finalizer and zeroes out its vtbl. It's _not_ null, and using it will likely result in a segfault (some non-virtual stuff may still work, but anything virtual will cause a segfault because of the zeroed out vtbl).

Calling clear on pretty much everything else is safe, since it generally just sets everything else to null without doing any kind of destruction or cleanup. The on exception would be structs, and with them, they get put in their init state if they're on the stack, and if they're on the heap, the pointer to them gets set to null. The struct itself is untouched. But for classes, it's _not_ safe. The object _does_ get put in an invalid state.

Stuff like initializing to void or calling clear on an object are really only there so that you have more fine-grained control when you really need it, and they come with definite responsibility when you do use them, because you're telling the language that you don't need its full protection and that you know what you're doing. They really shouldn't be used in your average D program.

- Jonathan M Davis
1 2 3 4 5 6
Next ›   Last »