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;
}
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 apointer to a pointer to a Color struct
to the function (which isgobject_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 (anullable Color
) is equivalent to aColor*
(apointer to Color
) in C.Vala translates
ref
andout
parameters to pointers in C as well, so you get a double pointer (pointer to a pointer
) when calling anout
orref
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.