[Vala] [BUG] Re: Closures and local variables



On Mon, Feb 07, 2011 at 15:03:38 +0100, Sylvain Leroux wrote:
I'm still having hard time using closures in Vala.

You found a bug in vala.

I suspect it's the same bug as:
https://bugzilla.gnome.org/show_bug.cgi?id=611460
https://bugzilla.gnome.org/show_bug.cgi?id=635194
https://bugzilla.gnome.org/show_bug.cgi?id=599133
and related
https://bugzilla.gnome.org/show_bug.cgi?id=608916

[...] 
There is no error on compilation. But the result is quite surprising:
    sh$ valac closure.vala 
    sh$ ./closure
    1 2 1
    1 2 1

It returned '1 0 -1' for me. That's because valac actually generated invalid
C code with undefined behaviour.

The problem, after inspecting the generated C is actually in the Pair
constructor:

delegate int SomeFunction();

class Pair {
    public SomeFunction    fa;
    public SomeFunction    fb;

    public Pair(SomeFunction fa, SomeFunction fb) {
      this.fa = fa;
      this.fb = fb;
        ^^^^^^^^^^^^^

Here, vala should give an error, because you are assigning the (by default)
unowned argument to the (by default) owned member. That conversion is however
not correct for delegate, because unowned delegate does not carry enough
information to correctly add a reference. In fact even owned delegate can
only be moved, not copied.

Unfortunately Debian does not have valac 0.11.5, so I tested with 0.10.3.

And it gets worse than that:

I modified the above to say:

    public Pair(owned SomeFunction fa, owned SomeFunction fb) {
        this.fa = fa;
        this.fb = fb;
    }

and it copied the delegate data, but *without* any attempt at incrementing
their refcounts and than immediately destroyed the ones from arguments, so
wrong code again.

Now that's not the end of it. The correct code should have been:

    public Pair(owned SomeFunction fa, owned SomeFunction fb) {
        this.fa = (owned)fa;
        this.fb = (owned)fb;
    }

and valac rejected the code, saying that:

   error: Reference transfer not supported for delegates

Now the problem is that reference transfer is what should have been done
here. Except it does not work.

-- 
                                                 Jan 'Bulb' Hudec <bulb ucw cz>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]