Re: Sinkability considered harmful

On Wed, 4 Jan 2006, Federico Mena Quintero wrote:

On Wed, 2006-01-04 at 12:33 +0100, Tim Janik wrote:

   1. "The main motivation for providing floating references is C convenience"

That's inaccurate.  We added floating references to avoid breaking
existing code.

i don't think that's inaccurate. C convenience is really why sinking makes sense for GtkObject and why it's considered/implemented for GObject derived
types or for pspecs or closures.

so asid for maintaining API compatibility, there is no technical need for
a floating flag.

Exactly!  And read on.

one can maintain your claim from a purely technical perspective.
however, it is not very helpfull for everyday coding in C. let's
investigate what the floating flag buys your in every day C code.

C is hard.

yes, which is why opportunities to ease coding are so
important to be made use of. be that adding convenience
functions, or possibly moving to C99 or adding macros
for type creation boilerpplate or ...

 Memory management in C is hard.

sounds like a good reason to ease it where possible.

People have to get over it.

well, i think the question here is whether we assist them with appropriate
functionality, or let everyone learn every possible memory management failure the hard way over and over again. the latter is prone to produce
bug-ridden software and be way less productive (see the mythical man month
on why it is important to reduce the klocs one has to write to achive
a given task).

To summarize the inconsistencies that we have right now:

1. some_object_new() may give you a floating or non-floating reference,
depending on whether SomeObject is a child of GtkObject or GObject.
Pain for the developer and language bindings.

GtkObject will continue to mark the initial reference floating, the point in
moving floating flags to GObject is to allow all GObjects to behave the
same way long-term.

2. Bar *foo_get_bar(Foo *foo) may or may not give you a new reference to
bar.  We don't always follow the convention that "get()" means you get a
new reference, and "peek()" means you don't get a new reference.  Pain
for the developer and language bindings.  Special pain for developers of
threaded applications.

i pointed out the getter problematic we were apporoaching early on and
proposed a set of possible solutions. no real convention came out of
this in the end due to lack of consensus. unfortunately, this was
shortly before gnome-hackers emails went into a public archive, so
i can just link to my own proposal from back then:

however, this can't be attributed to floating references.

3. g_object_get (obj, "property", @prop, NULL) gives you a new
reference.  Or does it?  I can never remember, so I always have to
consult the implementation of g_value_object_copy_value().  Pain for the
developer and language bindings.  This also makes
g_object_get (foo, "bar", ...) dangerously asymmetric with respect to

i think one of the earliest occourances of g_object_get() handing out
newly allocated objects, is GnomeCanvasLine::points, written by you
incidentally ;)
hmm, glancing over it again, it even seems to leak, since it's not using
g_value_set_boxed_take_ownership() ;)
anyway, the rule was meant to be that g_object_get() would always return
duplicated values, but for some types/cases that was deemed too inefficient,
and because we have no convention, we instead now have thigns like:
  G_VALUE_NOCOPY_CONTENTS - can be passed to G_VALUE_LCOPY() (which is used
                            to implement varargs _get() functions) to avoid
                            value copies for getters
  G_SIGNAL_TYPE_STATIC_SCOPE - avoid copying values passed in to signals.

Pain, pain, pain.

sure, the various special cases we have do suck. they should be attributed
to a missing convention on peek/get/dup implementations though, not really
related to the floating flag.

I do *not* want to propagate this sort of inconsistencies.

the main problems you face are related to getters, jumping on the floating
flag doesn't help here, as it's largely unrelated to the problems you
outline. allowing all GObjects to be sinkable is a step towards reducing
inconsistencies with object creation, not escalating it.

That is why
I advocate keeping floating references in GtkObject and GtkWidget as a
historical artifact, rather than as recommended practices.

allowing the floating flag to be used for all kinds of objects actually
allows constructors to be implemented more consistently.
your battle against allowing floating flags and sinking aside from the
GtkObject hierarchy is already lost, such flags have been added/are being
added to custom object implementations already (e.g. gimp_item_sink()).
albeit with varying APIs which are needed-to-fix-inconsistencies and
do/will require special casing with bindings.

GtkObject has *ONE* interesting feature, and it is not floating
references --- it is the ::destroy() method.  In particular, for
GtkWidget this of course means "ask your parent to unparent you and
disappear from the widget hierarchy right away".

i could disagree here and go into technical details, but i won't, it's
not part of our actual argument.

my point is that allowing a floating reference count in GObject has
the potential to unify existing floating flag implementations above
GtkObject, should get rid of possible bugs that tend to show up in
lots of code duplication and to allow LBs or similar code to generically
deal with object creation in a consistent manner.

API freeze for GNOME 2.14 is approaching quickly.  Can we please back
out GObject floating references soon?

no, there really is no point in that. even if we were to do that, we
couldn't hold off floating references for non-GtkObjects but GObjects
anyway. the results would just be more diverse/spread-out, produce
more special cases for code dealing with object creation and possibly
be buggy.
i.e. it'd cause many people more learning/care taking work, and is more
likely to cause further pain due to an increased likelyness for bugs and
inconsistencies. i think that's a strong argument towards allowing the
unification of floating/sink functionality in GObject.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]