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 336677 - Documentation for g_object_ref_sink() is incorrect
Documentation for g_object_ref_sink() is incorrect
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: docs
2.10.x
Other All
: Normal minor
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2006-03-31 00:10 UTC by Chris Vine
Modified: 2006-06-02 10:23 UTC
See Also:
GNOME target: ---
GNOME version: 2.13/2.14



Description Chris Vine 2006-03-31 00:10:16 UTC
Documentation 
Section: 
Increase the reference count of object, and possibly remove the floating
reference, if object has a floating reference.

Correct version:
It should say "If there is a floating reference, remove it, and if there is not,
increase the reference count."

Other information:
The entire code in the g_object_ref_sink() function in gobject.c is as follows:
{
  GObject *object = _object;
  gboolean was_floating;
  g_return_val_if_fail (G_IS_OBJECT (object), object);
  g_return_val_if_fail (object->ref_count >= 1, object);
  g_object_ref (object);
  was_floating = floating_flag_handler (object, -1);
  if (was_floating)
    g_object_unref (object);
  return object;
}

floating_flag_handler(object, -1), via object_floating_flag_handler(), removes
the floating reference (if it was set) and if it was set returns true.  Where it
returns true, g_object_unref() is called giving rise to no net increment of the
reference count.  Unlike a GtkObject, a GObject still begins with a reference
count of 1 (and g_object_ref_sink() will fail if the reference count is 0). 
That could also be made clearer in the documentation.
Comment 1 Matthias Clasen 2006-03-31 14:02:12 UTC
The language many not be the clearest, but  I believe that it basically says
the right thing. The important thing to keep in mind is that the floating reference is a regular reference, ie it contributes to the reference count. 
So, "removing the floating reference" means a) clear the floating flag and b) decreases the reference count. 
Comment 2 Chris Vine 2006-03-31 19:24:49 UTC
Yes, it gets the floating reference right.  However it says that if the floating reference is unset the reference count is still incremented.  It isn't (it doesn't work like a GtkObject where you call g_object_ref() and then gtk_object_sink(), where the floating reference is, so to speak, converted into a strong reference).  With g_object_ref_sink() the reference count is only increased if the floating reference is not set.  A similar point arises earlier in the documentation for GObject, where it incorrectly says "The floating reference can be converted into an ordinary reference by calling g_object_ref_sink()".  I think it important to make the point that it is different to the way GtkObjects work if people are not to get confused - I was until I looked at the source code and saw it was doing something different to what the documentation said.

Unfortunately without an API break, you still have to look at the class heirarchy, or some other documentation (I hope there will be some), to see whether an particular object will has g_object_ref_sink() called on it (ie it is an old style GtkObject) or whether it doesn't (it is an old style GObject).  In the latter case, to pass ownership to a container it will still be necessary to call g_object_unref() after putting it in the container in order not to break existing code - for example when placing a GtkTreeModel object in a GtkTreeView object.
Comment 3 Matthias Clasen 2006-04-01 15:43:12 UTC
g_object_ref_sink (foo) 

is exactly the same as

g_object_ref (foo);
gtk_object_sink (foo);

I don't see what your problem is, honestly. Can you point me at any difference
between the two ?
Comment 4 Chris Vine 2006-04-02 21:02:27 UTC
You are right that "g_object_ref(foo); gtk_object_sink(foo);" has the same effect as "g_object_ref_sink(foo)".  However the effect of neither:

g_object_ref(foo); gtk_object_sink(foo);

nor

g_object_ref_sink(foo);

is the effect claimed for in the documentation for g_object_ref_sink(), namely:

"Increase the reference count of object, and possibly remove the floating
reference, if object has a floating reference."

The real effect (of both sets of statements) is, as I said:

"If there is a floating reference, remove it, and if there is not, increase the reference count."

In other words, a GtkObject or new-style GObject begins life with a reference count of 1 and a floating reference, and after either of the sets of statements is called on it, it ends up with a reference count of 1 and no floating reference.

Getting the description right for a new-style GObject is more important because a GTK+ container will not necessarily take ownership of it and, if it does not, the user has to understand that she needs to call g_object_unref() on it to dispose of it and/or pass ownership to an object which will not call g_object_ref_sink() on it.  Finalising a GObject by calling g_object_unref() without having removed the floating reference does not generate a warning and is not regarded as mistake (it is necessary to retain compatibility with glib before version 2.10).  Finalising a GtkObject by calling g_object_unref() without having removed the floating reference does generate a warning, since they are intended for insertion in GTK+ containers.

I possibly misled you by saying that "Unlike a GtkObject, a GObject still begins with a reference count of 1".  Objects of both types begin with a reference count of 1, although as I said if you call g_object_unref() on a GtkObject object without having removed the floating reference, you will get a warning.  Although it would be inaccurate, it would not be a mistake to "picture" a GtkObject object as beginning life with a reference count of 0 and a floating reference, and after g_object_ref_sink() is called on it to picture it as ending up with a reference count of 1 and no floating reference.  It would be a mistake to picture a new-style GObject this way if it is not intended for placing in a GTK+ container (example: placing a GtkTreeModel object in a GtkTreeView object).

You are wrong that (in any formal sense):

"that the floating reference is a regular reference, ie it contributes to the reference count.  So, "removing the floating reference" means a) clear the floating flag and b) decreases the reference count."

It does not contribute to the reference count (or if you want to picture it that way, a new 
Comment 5 Chris Vine 2006-04-02 21:07:33 UTC
My last sentence was intended to say (I must have accidentally hit the magic key combination which sent the message):

"It does not contribute to the reference count, because calling g_object_unref() on a GObject object will dispose of it without doing anything further, and must do so to maintain compatibility."
Comment 6 Owen Taylor 2006-04-02 21:13:59 UTC
You seem to be missing the end of your comment, but as to "You are
wrong that...", it's not up to *you* to define the terminology we
use in the GLib docs. According to the maintainers of GLib, floating
references are references and contribute to the refcount. It's fine to
add explanatory text if necessary to clarify that ... the docs could
say something along the line of:
 
 "If the object is floating, then this call "assumes ownership" of
  the floating reference, converting it to a normal reference by
  clearing the floating flag while leaving the reference count 
  unchanged. If the object is not floating, then this call adds
  a new normal reference increasing the reference count by one."

Maybe the docs already say something to that effect... I haven't
checked. But your suggested change is completely and utterly wrong. 
You've misunderstood our terminology. Please readjust your understanding 
instead of campaigning to adjust our docs to your understanding.
Comment 7 Owen Taylor 2006-04-02 21:17:49 UTC
It's a bug to call g_object_unref() on an object that has only
a floating refcount. By doing that you are triggering undefined
behavior ... maybe we don't warn currently, but we traditionally
have done so for reference counts in GTK+.
 
Comment 8 Chris Vine 2006-04-02 22:39:35 UTC
It would a bug with a GtkObject.  With a new-style GObject, if you are not to break API it is not a bug to call g_object_unref() on an object that has a floating reference count, since that is how GObjects have always worked (before version 2.10 they have never had a floating reference count).  They have always begun with a reference count of 1, and are finalised by taking that count to 0.

Would it help if g_object_ref_sink() took a GInitiallyUnowned argument rather than a GObject argument.  I realise the two are typdef'ed to mean the same at present but presumably from what you say that is intended to change?
Comment 9 Chris Vine 2006-04-02 22:42:34 UTC
Actually I see the argument is a void* - the documentation says it is passed a GObject.  Perhaps it ought to say it is passed a GInitiallyUnowned object.
Comment 10 Chris Vine 2006-04-02 22:56:30 UTC
On your pre-penultimate comment, I think all that has been said that can be said, and as you say the glib maintainers can call a floating reference an addition to the reference count if they want to do so.  If they do so, in the case of a GObject on which g_object_ref_sink() has not been called - which as I have mentioned is not an error if you are to maintain API - you would have to regard g_object_unref as disposing of the floating reference and so finalising the object (even though it is not actually doing that).

However that would still not make the comment about g_object_ref_sink() correct:

"Increase the reference count of object, and possibly remove the floating
reference, if object has a floating reference."

It should say "Convert the floating reference to a strong reference, if the object has a floating reference, and if not increment the reference count."
Comment 11 Owen Taylor 2006-04-03 00:44:34 UTC
Not worth debating further, but leaving open since it wouldn't hurt
to add a few sentences to make it explicitly clear what the behavior is.
Comment 12 Matthias Clasen 2006-04-03 18:31:58 UTC
2006-04-03  Matthias Clasen  <mclasen@redhat.com>

	* gobject/tmpl/objects.sgml: Add some verbiage to 
	g_object_ref_sink_docs.  (#336677)
Comment 13 Chris Vine 2006-06-02 10:23:53 UTC
This change has also corrected the statement in the documentation (gobject/tmpl/objects.sgml) that all GObjects are created with a floating reference.  The documentation now states that GInitiallyUnowned objects are created with a floating reference. However this has only been applied to Glib-2.11.  The point about g_object_ref_sink() is a bit optional, but I suggest the statements about GObjects being created with a floating reference is corrected in the Glib-2.10 documentation (this point cropped up on one of the mailing lists).