View mode: basic / threaded / horizontal-split · Log in · Help
July 22, 2012
Re: ~= call copy ctor?
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
Re: ~= call copy ctor?
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
Re: ~= call copy ctor?
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
Re: ~= call copy ctor?
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
Re: ~= call copy ctor?
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
Re: ~= call copy ctor?
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
Re: ~= call copy ctor?
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
Re: ~= call copy ctor?
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
Next ›   Last »
2 3 4 5 6
Top | Discussion index | About this forum | D home