Vala: Understanding Struct Properties in Classes

865 views Asked by At

I am currently in the process of working my way through the Vala tutorial at https://wiki.gnome.org/Projects/Vala/Tutorial. Now I have stumbled across one section that I need some further explanation for; in the part on object properties at the very end the tutorial introduces struct properties. An example is given that illustrates how one retrieves such a property:

struct Color
{
    public uint32 argb;

    public Color() { argb = 0x12345678; }
}

class Shape: GLib.Object
{
    public Color c { get; set; default = Color(); }
}

int main()
{
    Color? c = null;
    Shape s = new Shape();
    s.get("c", out c);
}

The tutorial states: "This way, c is an reference instead of an instance of Color on stack. What you passed into s.get() is Color ** instead of Color *."

My question is about the statement above. First, could somebody please elaborate on what is meant by "What you passed into s.get() is Color ** instead of Color *.". Also, does this imply that the following

int main()
{
    Shape s = new Shape();
    Color c = s.c;
}

results in the value of s.c being assigned to c?

Edit: I ran the above example in valac -C structs.vala. The relevant C equivalent of the main method is

gint _vala_main (void) {
    gint result = 0;
    Color* c = NULL;
    Shape* s = NULL;
    Shape* _tmp0_ = NULL;
    c = NULL;
    _tmp0_ = shape_new ();
    s = _tmp0_;
    g_object_get ((GObject*) s, "c", &c, NULL);
    result = 0;
    _g_object_unref0 (s);
    _color_free0 (c);
    return result;
}
1

There are 1 answers

2
Jens Mühlenhoff On BEST ANSWER

valac compiles Vala code into C code which is then compiled by the C compiler (usually GCC) to the target format (e.g. an object file, a library or an executable).

So what the tutorial is talking about when saying Color** is that the generated C code will be passing a pointer to a pointer to a Color struct to the function (which is gobject_get in the generated C code).

Structs are value types in C and in Vala* which means that all their memory is copied on assignment. A Color? in Vala (a nullable Color) is equivalent to a Color* (a pointer to Color) in C.

Vala translates ref and out parameters to pointers in C as well, so you get a double pointer (pointer to a pointer) when calling an out or ref parameter with a nullable struct variable.

C is less strongly typed than Vala, that's the reason that a lot of Vala constructs end up being pointers in C. C uses pointer to state optional things, references, call-by-reference parameters, arrays / strings, linked lists and some other more obscure things (like function pointers and Generics).

As to your second question: A copy will be made* when directly assigning to a struct variable.

*See this question with a great answer by AlThomas which explains when copying is going on in the Vala and C levels.