Summary: | tp_list_connection_managers() (and others?) use const on complex types. | ||
---|---|---|---|
Product: | Telepathy | Reporter: | Murray Cumming <murrayc> |
Component: | tp-glib | Assignee: | Telepathy bugs list <telepathy-bugs> |
Status: | RESOLVED INVALID | QA Contact: | Telepathy bugs list <telepathy-bugs> |
Severity: | normal | ||
Priority: | medium | ||
Version: | unspecified | ||
Hardware: | Other | ||
OS: | All | ||
Whiteboard: | |||
i915 platform: | i915 features: |
Description
Murray Cumming
2008-10-13 03:26:56 UTC
Er, isn't this basically the same code as examples/client/list-managers.c? Except that the example handles errors correctly, while the code you pasted appears to dereference @cms even if @error is non-NULL, causing a segfault (@cms is documented as "... or %NULL on error". list-managers.c doesn't bother declaring an equivalent of your variable "cm" (it just uses *iter directly, since there's only one mention of it in the rest of the function) but the following patch to make it resemble your code compiles without warnings too. The problem is that you used "const TpConnectionManager *" where just "TpConnectionManager *" would do. TpConnectionManager * const * is a const pointer (pointer that you must not free) to TpConnectionManager *, so it is correct to dereference it and assign the result to a TpConnectionManager * variable. diff --git a/examples/client/list-managers.c b/examples/client/list-managers.c index 33e8aee..904e8b0 100644 --- a/examples/client/list-managers.c +++ b/examples/client/list-managers.c @@ -39,9 +39,10 @@ got_connection_managers (TpConnectionManager * const *cms, for (iter = cms; *iter != NULL; iter++) { + TpConnectionManager *cm = *iter; gchar *name; - g_object_get (*iter, + g_object_get (cm, "connection-manager", &name, NULL); (In reply to comment #1) > Er, isn't this basically the same code as examples/client/list-managers.c? > Except that the example handles errors correctly, while the code you pasted > appears to dereference @cms even if @error is non-NULL, causing a segfault > (@cms is documented as "... or %NULL on error". I left the error checking out on purpose to demonstrate more clearly the problem with const. Of course. > list-managers.c doesn't bother declaring an equivalent of your variable "cm" > (it just uses *iter directly, since there's only one mention of it in the rest > of the function) but the following patch to make it resemble your code compiles > without warnings too. The problem is that you used "const TpConnectionManager > *" where just "TpConnectionManager *" would do. > > TpConnectionManager * const * is a const pointer (pointer that you must not > free) to TpConnectionManager *, I thought that would be TpConnectionManager * * const because you can generally read pointer syntax backwards, but as I've said elsewhere pointer to pointer syntax is horrible and should be avoided. At the least, typedefs should be used to clarify it. I tried it and you seem to be right. Sorry. Thanks. pointer to pointer can be hidden with a typedef, just like GStrv for gchar**. This is useful for bindings too. For example a binding can generate a list of strings if it sees GStrv, but can't do anything if it is a GList* or a gchar**. What about that? typedef TpConnectionManagerArray TpConnectionManager* const*; Why not declare the parameter as TpConnectionManager * connection_managers [] That's equivalent and removes all confusion. Xavier, that doesn't add much (even when we correct your syntax). I was thinking more of typedef TpConnectionManager* TpConnectionManagerPtr; const TpConnectionManagerPtr* connection_managers; It's not pretty, but pointer-to-pointer never is (a GList would be better), but it is at least more readable. |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.