Helping newbies is fun

Helping people on gtk-app-devel-list is fun, especially when familiarizing them with C pitfalls. I’ve written a little lineup describing four common C pointer argument conventions:

1 void foo (const void *bar);

means that bar will definitly not be modified. While the foo author
could theoretically force to free or modify it, that would require casting the const away and whoever does it is on crack:
C uses call by value. So after invoking foo, which could do free ((void*)bar), and set its local copy of bar to NULL, the outer bar variable is undefined. Using it further will most likely result in a crash, including calling free (bar); in the outer frame again.

2 void foo (void **bar);

This is some sort of call by reference. You pass the address of the bar
variable, i.e. char *foobar = …; foo ((void **) &foobar); This syntax
ensures that the foo function can dereference its local copy of &foobar,
and make *bar (which is foobar) point to NULL after freeing, or
reallocate it – do all the pointer magic (except for pointer arithmetic,
because it is a void * pointer in this case).

3 void * foo (void *bar);

This will also work on the local copy of bar, and
– if it changes bar – return that changed value, i.e. the new address of its local bar copy. So you can invoke it
like char *foobar = …; foobar = foo (foobar);.

I’ve never seen any function acting like that, to be honest.

4 void * foo (const void *bar);

Just some flavor of 3, which will always return newly allocated memory
in addition to that already allocated for bar, while not modifying the
latter.
eel_str_strip_chr uses this variant.

Update:

Tollef points out that flavor 3 is used for realloc.

5 thoughts on “Helping newbies is fun”

  1. > I’ve never seen any function acting like that, to be honest.

    The GList and GSList functions work that way — you pass in the list head, and they return to you the potentially changed list head.

  2. Tollef: You’re totally right, thanks for pointing that out.

    anonymous: No, they don’t modify the location of the passed-in pointer, but the members of the struct the passed-in pointer points to.

  3. Chris, g_list_append modifies the pointer in the very special case, that you pass an empty list: You pass in the NULL pointer and you get back the pointer on a newly allocated list . g_list_prepend also returns another pointer than passed in.

  4. Mathias: g_list_append/prepend seems to malloc a new list as return value, no matter whether the argument is NULL or not. For the caller, this is completely transparent (because of call-by-value), but technically this is 4, with the const modifier removed. Just take a peek at the GList source code.

Comments are closed.