: GObject G_DECLARE macros considered harmful
The GObject library version 2.44 introduced the
G_DECLARE_DERIVABLE_TYPE() and
G_DECLARE_FINAL_TYPE() macros.
Most GNOME developers see these macros as a good thing, to avoid some boilerplate code.
I see these macros quite differently, and I avoid them because it creates more problems than it solves.
Old convention
Without the G_DECLARE_*() macros, the convention was to
always have a priv field in the object struct. To access a
private field, you write self->priv->foo, like this:
/* Old convention: have a 'priv' field in the object struct. */
gint
my_object_get_foo (MyObject *object)
{
return object->priv->foo;
}
With G_DECLARE
When using the G_DECLARE_*() macros, the above code becomes:
/* For a final type */
gint
my_object_get_foo (MyObject *object)
{
return object->foo;
}
/* For a derivable type */
gint
my_object_get_foo (MyObject *object)
{
MyObjectPrivate *priv = my_object_get_instance_private (object);
return priv->foo;
}
I see several problems with that approach:
-
Porting a big project to the
G_DECLARE_*()macros takes a significant amount of time! There are currently no refactoring tools to do it quickly. -
Calling
my_object_get_instance_private()in each function is quite cumbersome… - Changing between a final and derivable type is - as you can see - also a lot of mechanical work. So, even for new classes, I don't recommend using these macros!
So as a conclusion, I stick to the old way of implementing GObjects. There are anyway some tools to generate the boilerplate, see for example gdev-c-utils.
Edit: rewrote this blog post (in 2026).