I was reading about the language vala and that it compiles to Ansi C code. However I also saw it supports generics like Java or Rust. Now my question is how this is compiled to C code? If I have a gerneric class or function, what kind of C code is generated to simulate the generic behavior?
-
Say you write a generic `list
` and then use a `list – nwp Jul 04 '16 at 09:02` and a `list `. The Vala compiler will write C-structs `list_int` and `list_double` that have the appropriate behavior. In other words the work of instantiating a specific generic is done by Vala. -
1Wouldn't this be the same as C++ templates? But templates haven't the exactly same behavior as generics I think. – Exagon Jul 04 '16 at 09:05
-
C++ templates behave similarly to C# generics (as explained [here](http://stackoverflow.com/a/31929/69809)). It's the same way vala generics will create actual structs for each generic parameter you pass. – vgru Jul 04 '16 at 09:09
-
1C++ templates are not compiled into C-code, but the concept is the same. Of course the C-structs are written in a way to have the behavior that is correct according to Vala specs, not what C++ or C# say. – nwp Jul 04 '16 at 09:14
-
1@nwp Only one C struct is created, see my answer. – Jens Mühlenhoff Jul 04 '16 at 10:45
1 Answers
Vala generics are based on gpointer
and GType
.
You can only specialize a Generic class with a pointer based type parameter.
class MyClass<T> {
public T val;
}
public static int main (string[] args) {
// This wouldn't compile!
// var il = new Gee.ArrayList<int> ();
var il = new Gee.ArrayList<int?> ();
var dl = new Gee.ArrayList<double?> ();
il.add (5);
dl.add (3.0);
var im = new MyClass<int?>();
im.val = 5;
var dm = new MyClass<double?>();
dm.val = 3.0;
var lm = new MyClass< Gee.List<int?> > ();
lm.val = il;
return 0;
}
You can check the generated code yourself with the -C
parameter:
valac -C Main.vala --pkg gee-0.8
This will generate a main.c
file. If you read it carefully you will see there is only one struct for MyClass (plus some additional helper structs that are needed for GObject based classes) that has a member gpointer val
, it also has a GType t_type
as well as a t_dup_func
and a t_destroy_func
.
struct _MyClass {
// ...
gpointer val;
};
struct _MyClassPrivate {
GType t_type;
GBoxedCopyFunc t_dup_func;
GDestroyNotify t_destroy_func;
};
To ensure the correct type is passed in GLib type checking is performed. This makes Vala generics type safe (partially at compile time and partially at runtime).
This is in contrast with C++ templates which are expanded at compile time. So it is closer to C# generics than to classic C++ templates.
I wrote "partially at compile time" because the Vala compiler is smart enough to omit the type check in the C code when it knows that the assignment will always be correct.
Also Vala generated C code is meant to be easily consumable for other programming languages that have GLib bindings (like C, Python, C++, GJS, etc.)

- 14,565
- 6
- 56
- 113