telepath-glib seem to use Thing** when it really doesn't need to. This makes the API awkward, by requiring extra dereferencing, needing extra checks for NULL.
For instance, the TpConnectionManagerListCb callback provides a TpConnectionManager** parameter instead of just a TpConnectionManager*.
Also, for instance, TpConnectionManagerProtocol::protocols is a pointer to a pointer, but a simple pointer would be just as good for a NULL-terminated array of TpConnectionManagerProtocol:
This also encourages people to get confused between pointers to arrays, or arrays of pointers (telepathy-glib uses both), leading to weird memory access errors. I really hate this.
At the time that TpConnectionManagerListCb was written, the size of a TpConnectionManager was not yet fixed, so we couldn't use a packed array of them. The (TpConnectionManager **) is effectively the contents of a GPtrArray of (TpConnectionManager *), with some attempt at type-safety.
As far as I know, you also can't arrange for g_object_new() to allocate GObjects in an array. So, WONTFIX/CANTFIX.
The gtkdoc for TpConnectionManagerProtocol specifically says that its size is not yet fixed, so again, we can't have an array of TpConnectionManagerProtocol without breaking ABI if/when this size changes. WONTFIX/CANTFIX again.
I'll leave this bug open for the moment as a reminder that a cleaner API + deprecating the old API might be good to have.
So use a GSList then, like GTK+ would for similar API. Sure, g_object_new() can't allocate more than one object, so call it more than once.
(In reply to comment #2)
> At the time that TpConnectionManagerListCb was written, the size of a
> TpConnectionManager was not yet fixed, so we couldn't use a packed array of
> them. The (TpConnectionManager **) is effectively the contents of a GPtrArray
> of (TpConnectionManager *), with some attempt at type-safety.
I also don't see the sense of this. The size of a TpConnectionManager could affect the size of a struct if it had an array of them as a member field, but it's not going to affect the ABI when TpConnectionManager* is used as a function (or callback) parameter. Either way, the application needs to know how big the TpConnectionManager is. Requiring an extra dereference doesn't change that.
And the struct implementations should be private, using the GObject priv system, ideally, so there won't be a problem with base sizes changing.
One advantage of using Foo ** is that you do not have to cast while iterating across the array, and the type of elements of the list is right there in the type signature; when using GSLists, it's easy to get the type wrong.
tp_list_connection_managers_async() and tp_connection_manager_dup_protocols() supersede the constructs that Murray didn't like, so I think we can call this FIXED.
The superseded things are on their way out too (I have a branch that deprecates them for 0.20, after which I'll delete them from the incompatible 'next' branch which will become 1.0).