View mode: basic / threaded / horizontal-split · Log in · Help
November 12, 2012
Compiler bug? (alias sth this; and std.signals)
Ok, i was trying out D and wanted to see if i could create 
something that behaves like a property but adds a change 
notification signal. Doing this, I encountered a hangup which 
might be a bug. So far I have the following:

-----------------------------------------------------------

import std.signals;
import std.stdio;

struct Property
{
	alias get this;
	
	int set(int v) { emit(); return data_ = v; }
	int get() { return data_; }
	
	int opAssign(int v) { return set(v); }
	
	mixin Signal!();

private:
	int data_ = 0;
}

struct Foo
{
	Property prop;
}

class Observer
{
	void watch()
	{
		writeln("Value change observed!");
	}
}

-----------------------------------------------------------

This works:
void main()
{
	Foo f;
	Observer o = new Observer;
	f.prop.connect(&o.watch);
	f.prop = 7;
}

This also works:
void main()
{
	Foo f;
	Observer o = new Observer;
	f.prop = 7;
	writeln(f.prop);
}

This never terminates:
void main()
{
	Foo f;
	Observer o = new Observer;
	f.prop.connect(&o.watch);
	f.prop = 7;
	writeln(f.prop);
}
November 13, 2012
Re: Compiler bug? (alias sth this; and std.signals)
No one? Is this a bug, or am I overlooking something? (entirely 
possible since I didn't use D since trying it once in D1 times)

On Monday, 12 November 2012 at 11:59:50 UTC, Joe wrote:
> Ok, i was trying out D and wanted to see if i could create 
> something that behaves like a property but adds a change 
> notification signal. Doing this, I encountered a hangup which 
> might be a bug. So far I have the following:
>
> -----------------------------------------------------------
>
> import std.signals;
> import std.stdio;
>
> struct Property
> {
> 	alias get this;
> 	
> 	int set(int v) { emit(); return data_ = v; }
> 	int get() { return data_; }
> 	
> 	int opAssign(int v) { return set(v); }
> 	
> 	mixin Signal!();
>
> private:
> 	int data_ = 0;
> }
>
> struct Foo
> {
> 	Property prop;
> }
>
> class Observer
> {
> 	void watch()
> 	{
> 		writeln("Value change observed!");
> 	}
> }
>
> -----------------------------------------------------------
>
> This works:
> void main()
> {
> 	Foo f;
> 	Observer o = new Observer;
> 	f.prop.connect(&o.watch);
> 	f.prop = 7;
> }
>
> This also works:
> void main()
> {
> 	Foo f;
> 	Observer o = new Observer;
> 	f.prop = 7;
> 	writeln(f.prop);
> }
>
> This never terminates:
> void main()
> {
> 	Foo f;
> 	Observer o = new Observer;
> 	f.prop.connect(&o.watch);
> 	f.prop = 7;
> 	writeln(f.prop);
> }
November 13, 2012
Re: Compiler bug? (alias sth this; and std.signals)
The third version using dmd 2.060 linux crashes. Valgrind shows 
lots of errors (other two are clean) relating to corrupted heap 
caused likely here 
(https://github.com/D-Programming-Language/phobos/blob/master/std/signals.d#L248) 
which is not surprising judging by semi-manual memory management 
in __dtor. I guess either you are abusing library feature or 
found a bug. Consider posting this to Bugzilla.
November 13, 2012
Re: Compiler bug? (alias sth this; and std.signals)
Not a compiler bug. A bug in the implementation of std.signals.
> > 	writeln(f.prop);

Property is a struct and thus it is passed by value, which means that
the signal is copied. Signal does not define a postblit constructor,
because it was intended to be used in classes, so a bitwise copy is
done. Meaning that the internal allocated storage is freed twice.

If used in a class there is no issue with copying a signal, because it
is a mixin and does not exist on its own and an object has reference
semantics.

I am already working on a replacement for std.signals which fixes some
of its shortcomings. It will also fix this one.

Best regards,

Robert
November 14, 2012
Re: Compiler bug? (alias sth this; and std.signals)
In your particular case, which this definitely is a bug and if only for
missing documentation that you should only use it from classes, you
might regardless be better of with writeln(f.prop.get) because you avoid
the needless copy with memory allocation/deallocation (if done
correctly) of the signal.

Passing f.prop directly should be possible for any function that takes
an int, but not for generic template functions because then you pass the
struct directly.

Best regards,

Robert
November 14, 2012
Re: Compiler bug? (alias sth this; and std.signals)
On Tuesday, 13 November 2012 at 22:55:38 UTC, eskimo wrote:
> Property is a struct and thus it is passed by value, which 
> means that
> the signal is copied.

But wait! Due to "alias get this;", f.prop shouldn't copy prop
but call get (which it does in the working - second - case)!

How to check? Remove the alias and writeln(f.prop) prints
"Property(7)", with the alias writeln(f.prop) prints "7"
November 14, 2012
Re: Compiler bug? (alias sth this; and std.signals)
> 
> But wait! Due to "alias get this;", f.prop shouldn't copy prop
> but call get (which it does in the working - second - case)!
-> Also here the struct is copied, but the signal has no content yet and
thus no memory allocation yet occurred. (So no double free)
> 
> How to check? Remove the alias and writeln(f.prop) prints
> "Property(7)", with the alias writeln(f.prop) prints "7"

It should copy f.prop and it does. Your check results have another
explanation: writefln is a complete generic templated function, it has
no way of knowing that you want to pass the contained integer instead of
the struct. So by default it takes the struct (it has no requirements
that would lead to trigger the alias this). Eventually it will call some
function taking concrete arguments for printing the data. This concrete
function is not overloaded for your struct so the alias this to int
triggers now and the overload for int is being called. 

But first it is copied to every generic function that might be called on
the way.
November 15, 2012
Re: Compiler bug? (alias sth this; and std.signals)
On Wednesday, 14 November 2012 at 09:31:47 UTC, eskimo wrote:
> But first it is copied to every generic function that might be 
> called on
> the way.

Ok, I guess it just doesn't do what I understood it to do (which 
is too bad, but to be expected with a new language). In any case 
you would appear to be correct, as

void main()
{
	Foo f;
	Observer o = new Observer;
	f.prop.connect(&o.watch);
	f.prop = 7;
	writeln(f.prop.get);
}

works. It just doesn't look like intended.
November 15, 2012
Re: Compiler bug? (alias sth this; and std.signals)
On Thu, 2012-11-15 at 09:53 +0100, Joe wrote:
> On Wednesday, 14 November 2012 at 09:31:47 UTC, eskimo wrote:
> > But first it is copied to every generic function that might be 
> > called on
> > the way.
> 
> Ok, I guess it just doesn't do what I understood it to do (which 
> is too bad, but to be expected with a new language). In any case 
> you would appear to be correct, as
> 
> void main()
> {
> 	Foo f;
> 	Observer o = new Observer;
> 	f.prop.connect(&o.watch);
> 	f.prop = 7;
> 	writeln(f.prop.get);
> }
> 
> works. It just doesn't look like intended.

Well if signal had a proper postblit constructor your original way of
doing it would work. It is just not as efficient, but this is a price
you have to pay. The compiler has no way of knowing that you intended to
pass the contained int from the beginning, when you are actually passing
the containing struct.

But, considering that the alias this triggers only when you are issuing
an operation not supported by the struct itself, it is pretty reasonable
behaviour and everything else would be pretty surprising.

Best regards,

Robert
November 15, 2012
Re: Compiler bug? (alias sth this; and std.signals)
On Thursday, 15 November 2012 at 09:37:55 UTC, eskimo wrote:
>
> But, considering that the alias this triggers only when you are 
> issuing
> an operation not supported by the struct itself, it is pretty 
> reasonable
> behaviour and everything else would be pretty surprising.
>
> Best regards,
>
> Robert

I wonder though why it works at all then, because without the
alias the string conversion *is* supported and produces
"Property(7)".
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home