Sébastien Wilmet

: 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:

  1. 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.
  2. Calling my_object_get_instance_private() in each function is quite cumbersome…
  3. 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).