RFC: warnings on ignoring return value on some list operations



We recently had a bug in Nautilus where the return value from
g_list_sort() was ignored. These sorts of bugs are not all that uncommon
given the GList api, since its easy to forget the return value and from
an OO point of view g_list_sort (list) looks very right.

The attached patch adds a define for the gcc warn_unused_result function
attribute, and uses it in a few list operations. 

I tried to be conservative in adding them, doing so only if it seems
unreasonable to assume the programmer knew it was safe to ignore the
return value. I.e. with g_list_prepend its never safe to ignore it, but
with g_list_append its safe if you know the list isn't empty.

Another example is g_list_remove(), where I think its uncommon to know
that the removed item isn't first in the list, whereas I didn't add one
for g_list_remove_link() since in that case its more likely that you
know the position of the link.

What do people think about this?

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl redhat com    alla lysator liu se 
He's a shy albino shaman plagued by the memory of his family's brutal murder. 
She's a sharp-shooting streetsmart magician's assistant who dreams of becoming 
Elvis. They fight crime! 
Index: glib/gmacros.h
===================================================================
RCS file: /cvs/gnome/glib/glib/gmacros.h,v
retrieving revision 1.26
diff -u -p -r1.26 gmacros.h
--- glib/gmacros.h	8 Mar 2005 05:41:42 -0000	1.26
+++ glib/gmacros.h	24 Nov 2005 09:59:26 -0000
@@ -95,6 +95,13 @@
 #define G_GNUC_DEPRECATED
 #endif /* __GNUC__ */
 
+#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define G_GNUC_WARN_UNUSED_RESULT 		\
+  __attribute__((warn_unused_result))
+#else
+#define G_GNUC_WARN_UNUSED_RESULT
+#endif /* __GNUC__ */
+
 /* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
  * macros, so we can refer to them as strings unconditionally.
  * usage not-recommended since gcc-3.0
Index: glib/glist.h
===================================================================
RCS file: /cvs/gnome/glib/glib/glist.h,v
retrieving revision 1.8
diff -u -p -r1.8 glist.h
--- glib/glist.h	8 Nov 2002 18:47:54 -0000	1.8
+++ glib/glist.h	24 Nov 2005 09:59:26 -0000
@@ -44,34 +44,34 @@ struct _GList
  */
 void     g_list_push_allocator (GAllocator       *allocator);
 void     g_list_pop_allocator  (void);
-GList*   g_list_alloc          (void);
+GList*   g_list_alloc          (void) G_GNUC_WARN_UNUSED_RESULT;
 void     g_list_free           (GList            *list);
 void     g_list_free_1         (GList            *list);
 GList*   g_list_append         (GList            *list,
 				gpointer          data);
 GList*   g_list_prepend        (GList            *list,
-				gpointer          data);
+				gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
 GList*   g_list_insert         (GList            *list,
 				gpointer          data,
 				gint              position);
 GList*   g_list_insert_sorted  (GList            *list,
 				gpointer          data,
-				GCompareFunc      func);
+				GCompareFunc      func) G_GNUC_WARN_UNUSED_RESULT;
 GList*   g_list_insert_before  (GList            *list,
 				GList            *sibling,
 				gpointer          data);
 GList*   g_list_concat         (GList            *list1,
 				GList            *list2);
 GList*   g_list_remove         (GList            *list,
-				gconstpointer     data);
+				gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
 GList*   g_list_remove_all     (GList            *list,
-				gconstpointer     data);
+				gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
 GList*   g_list_remove_link    (GList            *list,
 				GList            *llink);
 GList*   g_list_delete_link    (GList            *list,
 				GList            *link_);
-GList*   g_list_reverse        (GList            *list);
-GList*   g_list_copy           (GList            *list);
+GList*   g_list_reverse        (GList            *list) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_copy           (GList            *list) G_GNUC_WARN_UNUSED_RESULT;
 GList*   g_list_nth            (GList            *list,
 				guint             n);
 GList*   g_list_nth_prev       (GList            *list,
@@ -92,10 +92,10 @@ void     g_list_foreach        (GList   
 				GFunc             func,
 				gpointer          user_data);
 GList*   g_list_sort           (GList            *list,
-				GCompareFunc      compare_func);
+				GCompareFunc      compare_func)  G_GNUC_WARN_UNUSED_RESULT;
 GList*   g_list_sort_with_data (GList            *list,
 				GCompareDataFunc  compare_func,
-				gpointer          user_data);
+				gpointer          user_data)  G_GNUC_WARN_UNUSED_RESULT;
 gpointer g_list_nth_data       (GList            *list,
 				guint             n);
 
Index: glib/gslist.h
===================================================================
RCS file: /cvs/gnome/glib/glib/gslist.h,v
retrieving revision 1.6
diff -u -p -r1.6 gslist.h
--- glib/gslist.h	8 Nov 2002 18:47:54 -0000	1.6
+++ glib/gslist.h	24 Nov 2005 09:59:26 -0000
@@ -43,34 +43,34 @@ struct _GSList
  */
 void     g_slist_push_allocator (GAllocator       *allocator);
 void     g_slist_pop_allocator  (void);
-GSList*  g_slist_alloc          (void);
+GSList*  g_slist_alloc          (void)  G_GNUC_WARN_UNUSED_RESULT;
 void     g_slist_free           (GSList           *list);
 void     g_slist_free_1         (GSList           *list);
 GSList*  g_slist_append         (GSList           *list,
 				 gpointer          data);
 GSList*  g_slist_prepend        (GSList           *list,
-				 gpointer          data);
+				 gpointer          data)  G_GNUC_WARN_UNUSED_RESULT;
 GSList*  g_slist_insert         (GSList           *list,
 				 gpointer          data,
 				 gint              position);
 GSList*  g_slist_insert_sorted  (GSList           *list,
 				 gpointer          data,
-				 GCompareFunc      func);
+				 GCompareFunc      func)  G_GNUC_WARN_UNUSED_RESULT;
 GSList*  g_slist_insert_before  (GSList           *slist,
 				 GSList           *sibling,
 				 gpointer          data);
 GSList*  g_slist_concat         (GSList           *list1,
 				 GSList           *list2);
 GSList*  g_slist_remove         (GSList           *list,
-				 gconstpointer     data);
+				 gconstpointer     data)  G_GNUC_WARN_UNUSED_RESULT;
 GSList*  g_slist_remove_all     (GSList           *list,
-				 gconstpointer     data);
+				 gconstpointer     data)  G_GNUC_WARN_UNUSED_RESULT;
 GSList*  g_slist_remove_link    (GSList           *list,
 				 GSList           *link_);
 GSList*  g_slist_delete_link    (GSList           *list,
 				 GSList           *link_);
-GSList*  g_slist_reverse        (GSList           *list);
-GSList*  g_slist_copy           (GSList           *list);
+GSList*  g_slist_reverse        (GSList           *list)  G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_copy           (GSList           *list)  G_GNUC_WARN_UNUSED_RESULT;
 GSList*  g_slist_nth            (GSList           *list,
 				 guint             n);
 GSList*  g_slist_find           (GSList           *list,
@@ -88,10 +88,10 @@ void     g_slist_foreach        (GSList 
 				 GFunc             func,
 				 gpointer          user_data);
 GSList*  g_slist_sort           (GSList           *list,
-				 GCompareFunc      compare_func);
+				 GCompareFunc      compare_func)  G_GNUC_WARN_UNUSED_RESULT;
 GSList*  g_slist_sort_with_data (GSList           *list,
 				 GCompareDataFunc  compare_func,
-				 gpointer          user_data);
+				 gpointer          user_data)  G_GNUC_WARN_UNUSED_RESULT;
 gpointer g_slist_nth_data       (GSList           *list,
 				 guint             n);
 #define  g_slist_next(slist)	((slist) ? (((GSList *)(slist))->next) : NULL)


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