11

I am using GLib's doubly linked list structure, GList. I would like to know if there is any standard macro for iterating over a GList. I couldn't find any such thing in the GLib documentation. As a result I have made my own macro, but I'd rather use something standard if it exists.

To Illustrate the the issue: Usually I write a lot of code which looks like this:

GList *list, *elem;
MyType *item;

for(elem = list; elem; elem = elem->next) {
  item = elem->data;
  /* do something with item */
}

With a macro it can be reduced to

GList *list;
MyType *item;

GFOREACH(item, list) {
  /* do something with item */
}

Which is much less noisy.


Note: I realised that GLib supplies a foreach function for iterating over a list and calling a callback for each element, but often the indirection of a callback makes the code harder to read, especially if the callback is only used once.


Update: seeing as there is no standard macro, I'm putting the macro I am using here in case it is of any use to someone else. Corrections/improvements are welcome.

#define GFOREACH(item, list) for(GList *__glist = list; __glist && (item = __glist->data, true); __glist = __glist->next)
Goaler444
  • 2,591
  • 6
  • 35
  • 53
James
  • 3,597
  • 2
  • 39
  • 38
  • I'm pretty sure GLib only provides the foreach functions for iterating over its various data structures. I agree, it's not always great for readability - though with a descriptive name for the callback it usually looks okay to me. – Cascabel Oct 23 '09 at 06:43

1 Answers1

7

There is no such macro.

I usually use a for loop like in your example unless the operation spans more than, say, fifteen lines, in which case I usually find that an extra foreach function with a descriptive name is more readable than the alternative.

What you may not realize is that you don't necessarily have to write your own foreach function:

g_list_foreach(list, (GFunc)g_free, NULL);

frees each item in the list, an operation that I often use.

ptomato
  • 56,175
  • 13
  • 112
  • 165
  • 2
    Note: For freeing a list, Glib now offers g_list_free_full(), http://developer.gnome.org/glib/2.28/glib-Doubly-Linked-Lists.html#g-list-free-full . That's probably more idiomatic for freeing a complete list (though I guess it does the same thing internally). – sleske Oct 31 '11 at 08:31