GNOME Bugzilla – Bug 620263
Add g_clear_object, g_clear_pointer, g_clear_boxed
Last modified: 2010-11-08 23:23:13 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.)
Created attachment 162461 [details] [review] proposed addition to GLib
Created attachment 162462 [details] [review] proposed addition to GObject
Also available in a git repository: the clear-object branch in git+ssh://people.freedesktop.org/~smcv/glib
Created attachment 166646 [details] [review] updated patch relative to master, post 2.25.11
Created attachment 166647 [details] [review] updated GObject patch relative to master, post 2.25.11
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.
(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);
(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.
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.
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.