After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 620263 - Add g_clear_object, g_clear_pointer, g_clear_boxed
Add g_clear_object, g_clear_pointer, g_clear_boxed
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
2.25.x
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2010-06-01 14:38 UTC by Simon McVittie
Modified: 2010-11-08 23:23 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
proposed addition to GLib (4.24 KB, patch)
2010-06-01 14:39 UTC, Simon McVittie
none Details | Review
proposed addition to GObject (7.03 KB, patch)
2010-06-01 14:39 UTC, Simon McVittie
none Details | Review
updated patch relative to master, post 2.25.11 (4.38 KB, patch)
2010-07-27 14:15 UTC, Simon McVittie
none Details | Review
updated GObject patch relative to master, post 2.25.11 (7.48 KB, patch)
2010-07-27 14:15 UTC, Simon McVittie
none Details | Review

Description Simon McVittie 2010-06-01 14:38:36 UTC
It's often useful to have a single easy function or macro to destroy the contents of a pointer variable and set it to NULL; it's even better if it's safe to call that macro with argument NULL. This can get rid of most of the boilerplate code in destructors and similar; for instance, Python has Py_CLEAR.

GLib has this for GError (with g_clear_error), but not for anything else so far. I propose to add g_clear_pointer to GLib, and g_clear_object and g_clear_boxed to GObject.

Conceptually, their prototypes are:

    void g_clear_pointer (gpointer *, GDestroyNotify);
    void g_clear_object (GObject **);
    void g_clear_boxed (GType, gpointer *);

but they're implemented as macros so that you can use pointers to any other suitable type without casting or violating strict aliasing.

(I recently added similar macros to telepathy-glib.)
Comment 1 Simon McVittie 2010-06-01 14:39:05 UTC
Created attachment 162461 [details] [review]
proposed addition to GLib
Comment 2 Simon McVittie 2010-06-01 14:39:23 UTC
Created attachment 162462 [details] [review]
proposed addition to GObject
Comment 3 Simon McVittie 2010-06-01 14:40:34 UTC
Also available in a git repository: the clear-object branch in git+ssh://people.freedesktop.org/~smcv/glib
Comment 4 Simon McVittie 2010-07-27 14:15:03 UTC
Created attachment 166646 [details] [review]
updated patch relative to master, post 2.25.11
Comment 5 Simon McVittie 2010-07-27 14:15:41 UTC
Created attachment 166647 [details] [review]
updated GObject patch relative to master, post 2.25.11
Comment 6 Allison Karlitskaya (desrt) 2010-08-06 16:48:13 UTC
g_clear_object is the only one that I really think would be generally useful
and g_set_object would be nice to go with it.
Comment 7 Simon McVittie 2010-08-09 09:52:31 UTC
(In reply to comment #6)
> g_clear_object is the only one that I really think would be generally useful

g_clear_object is (currently) implemented in terms of g_clear_pointer, and when porting Telepathy code to use the telepathy-glib versions of these macros, if anything I've ended up using tp_clear_pointer more often than tp_clear_object (for instance, "tp_clear_pointer (&self->priv->things, g_hash_table_unref)" is becoming a common idiom for our dispose callbacks). So, I'd really prefer to keep that one.

g_clear_boxed is less commonly useful, since any boxed type necessarily has a suitable GDestroyNotify implementation; it's useful for boxed types where the free function is either non-obvious, or was not made extern because the type author considered  g_boxed_free (TYPE, instance) to be sufficient. I think we've mostly used it when dealing with dbus-glib's parameterized types.

> and g_set_object would be nice to go with it.

Would that be essentially this functionality, but as a macro with more strict-aliasing compliance?

    GObject **obj_ptr;
    GObject *new_object;

    g_clear_object (obj_ptr);

    if (new_object)
      *obj_ptr = g_object_ref (new_object);
Comment 8 Guillaume Desmottes 2010-08-09 09:59:43 UTC
(In reply to comment #7)
> (In reply to comment #6)
> > g_clear_object is the only one that I really think would be generally useful
> 
> g_clear_object is (currently) implemented in terms of g_clear_pointer, and when
> porting Telepathy code to use the telepathy-glib versions of these macros, if
> anything I've ended up using tp_clear_pointer more often than tp_clear_object
> (for instance, "tp_clear_pointer (&self->priv->things, g_hash_table_unref)" is
> becoming a common idiom for our dispose callbacks). So, I'd really prefer to
> keep that one.

Agreed, I use it a lot in Telepathy and Empathy code.
Comment 9 Allison Karlitskaya (desrt) 2010-08-09 13:47:43 UTC
re comment 7:

The order might be a little bit different (ie: acquire the ref on the incoming object before dropping the ref on the old one) but yes.

Also, probably I'd attempt to figure out a clever way to avoid multiple-accessing and would also try to write the macro in a way that triggers a warning/error if the two pointers are incompatible.
Comment 10 Allison Karlitskaya (desrt) 2010-11-08 23:23:13 UTC
commit 1a1fc130ece13a442dcacaba1db9108089cead38
Author: Ryan Lortie <desrt@desrt.ca>
Date:   Mon Nov 8 16:42:32 2010 -0500

    New function: g_clear_object()
    
    By analogy to g_clear_error, takes a pass-by-reference GObject reference
    and, if non-%NULL, unrefs it and sets it equal to %NULL.
    
    Bug #620263.


I don't think we want to take the generic pointer or boxed versions.  They're just not convenient enough to justify adding them.