Search code examples
pointersvala

Owned attribute used in Vala function call creates "black magic C code"


This is an example in Vala code.

There is a global Glib.Llist vstack that stores some pointers.

List<void*> vstack;

There is a change_state function that stored the second parameter in the global vstack list.

void change_state( enum..., void*, enum... );

This goto_info test function (which calls change_state) doesn't work because, when it returns, the pointer is deallocated even if it is stored in the list

// Vala source
void goto_info()
{
    StInfo sti = new StInfo();
    change_state( SUPS.INFO_PAGE, sti, StackDir.FORW );
}

// C output
void goto_info (void) {
    StInfo* sti = NULL;
    StInfo* _tmp0_ = NULL;
    _tmp0_ = st_info_new ();
    sti = _tmp0_;
    change_state (SUPS_INFO_PAGE, sti, STACK_DIR_FORW);
    _g_object_unref0 (sti);
}

But if I just add the owned attribute, the code works (the pointer is not deallocated at the end of the goto_info function), but I really can't understand what changes in the C output.

// Vala source
void goto_info()
{
    StInfo sti = new StInfo();
    change_state( SUPS.INFO_PAGE, ( owned )sti, StackDir.FORW );
}

// C output
void goto_info (void) {
    StInfo* sti = NULL;
    StInfo* _tmp0_ = NULL;
    StInfo* _tmp1_ = NULL;
    _tmp0_ = st_info_new ();
    sti = _tmp0_;
    _tmp1_ = sti;
    sti = NULL;
    change_state (SUPS_INFO_PAGE, _tmp1_, STACK_DIR_FORW);
    _g_object_unref0 (sti);
}

IMPORTANT: goto_info is the only function that changes if I add owned, nothing else is touched by the Vala compiler. Someone can explain where is the black magic hidden in this C output code? Why the second version works if the ref/unref call for the pointer are the same?


Solution

  • Note this line:

    sti = NULL;
    

    sti is set to NULL (while _tmp1_ is passed to change_state instead), so the call to unref now is a noop:

    _g_object_unref0 (sti);