Implementing a GSource produces uncompilable C code with recent versions of valac
Implementing a GSource with the following Vala code:
void main () {
Source a = new QuitApplicationSource ();
}
class QuitApplicationSource:Source {
public override bool prepare (out int timeout) {
return false;
}
public override bool check () {
return false;
}
public override bool dispatch (SourceFunc callback) {
return false;
}
}
produces the follow errors from the C compiler:
quit_as_gsource.vala.c: In function ‘quit_application_source_instance_init’:
quit_as_gsource.vala.c:108:20: error: ‘GSource {aka struct _GSource}’ has no member named ‘prepare’
((GSource *) self)->prepare = (gboolean (*) (GSource *, gint*)) quit_application_source_real_prepare;
^
quit_as_gsource.vala.c:109:20: error: ‘GSource {aka struct _GSource}’ has no member named ‘check’
((GSource *) self)->check = (gboolean (*) (GSource *)) quit_application_source_real_check;
^
quit_as_gsource.vala.c:110:20: error: ‘GSource {aka struct _GSource}’ has no member named ‘dispatch’
((GSource *) self)->dispatch = (gboolean (*) (GSource *, GSourceFunc, gpointer)) quit_application_source_real_dispatch;
^
error: cc exited with status 256
This is because of this generated C function from the Vala compiler:
static void
quit_application_source_instance_init (QuitApplicationSource * self)
{
((GSource *) self)->prepare = (gboolean (*) (GSource *, gint*)) quit_application_source_real_prepare;
((GSource *) self)->check = (gboolean (*) (GSource *)) quit_application_source_real_check;
((GSource *) self)->dispatch = (gboolean (*) (GSource *, GSourceFunc, gpointer)) quit_application_source_real_dispatch;
}
Compiling this with valac
0.30.2 does not generate the error. With that version valac
produces an empty quit_application_source_instance_init
. This is probably something to do with the recent changes to abstract/virtual methods in compact classes.
In glib-2.0.vapi
the methods prepare
, check
and dispatch
are bound as abstract
. That is fine according to my understanding, but abstract means the implementation must have a method of that name. Also the binding has the methods marked with the protected
modifier - not sure why. I would expect the code generated in quit_application_source_instance_init
for a virtual
method. For abstract methods my understanding is there is only a compile time check that a method of that name has been implemented.