Does passing an object as property increment its refcount?

g_object_new (MY_OBJ_TYPE, "other-obj", other_obj, NULL);

Does this increment other_obj’s reference count? I have this set_property method as well.

static void
my_obj_set_property (GObject* object,
                     guint property_id,
                     const GValue* value,
                     GParamSpec* pspec)
{
  MyObj *self = MY_OBJ (object);

  switch (property_id)
    {
    case PROP_OTHER_OBJ:
      {
        self->other_obj = g_value_get_object (value);
        break;
      }
    }
}

It is unclear to me whether this increments it or not.

EDIT: I don’t want to increment it btw.

The documentation for g_value_get_object() says that the returned data is owned by the GValue instance—i.e. the returned value is annotated as transfer none—which means that MyObj does not acquire a reference on the object instance passed to the other-obj property. If that were the case, you’d see g_value_dup_object() instead.

From an idiomatic code perspective, the other-obj implementation is problematic: now MyObj and the other object instance share an implicit lifetime. Idiomatic code inside MyObj would do either of these two:

  1. acquire a reference to the other object inside the setter function, and release it inside its dispose() implementation
  2. add a weak reference to the other object, and nullify the pointer in the MyObj instance structure when the weak reference callback is invoked

Otherwise, if the other object instance disappears before MyObj, the other_obj pointer will contain garbage and will—if you’re lucky—cause a crash on access.

But the const GValue* takes a reference ain’t it? I’m supposing it gets freed, so by the time g_object_new returns, it is already decremented.

When you call g_object_new() (or g_object_set()), GObject will box the instance pointer inside a GValue, and that GValue will acquire a reference to the instance. The reference held by GValue will be released when the GValue is cleared using g_value_unset(), which happens at the end of g_object_new() (or g_object_set()), before control returns to the caller. This means that the instance is guaranteed to be valid for the duration of the call, but not after.

1 Like