function in glib/gqueue.c relies on undefined behavour?



Hi all,

I stumbled upon the implementation of the function
g_queue_free_full from glib/gqueue.c and there is
something I don't understand:

it takes a unary function as input, i.e.
something of type

void (*) (void *)

and forward it (to the function g_queue_foreach)
as a binary function, by casting it to the type

void (*) (void *, void *)

For the records, the second argument
(which is meant to be "discarded", I guess)
gets the value NULL.

At first sight, I would have imagined that
this is not valid C code, but lives in the gray land
of indefined behaviours;
you can't give two arguments to a function that requires only one!
But it compiles, and work as expected (the second arg
is actually ignored).

Am I missing something?

Here a code snippet the resume the situation;
it is taken from glib/gqueue.c and glib/gtypes.h.
It doesn't compile, it's just to put all definitions
in the same place to better explain what I mean.

--------8<--------------------------
typedef void* gpointer;
typedef void  (*GFunc)          (gpointer data,
                                 gpointer user_data);
typedef void  (*GDestroyNotify) (gpointer       data);

void
g_queue_free_full (GQueue         *queue,
		   GDestroyNotify  free_func)
{
  g_queue_foreach (queue, (GFunc) free_func, NULL);
  g_queue_free (queue);
}

void
g_queue_foreach (GQueue   *queue,
		 GFunc     func,
		 gpointer  user_data)
{
  GList *list;

  g_return_if_fail (queue != NULL);
  g_return_if_fail (func != NULL);

  list = queue->head;
  while (list)
    {
      GList *next = list->next;
      func (list->data, user_data);
      list = next;
    }
}
--------8<--------------------------

Again for the record, the function g_queue_free_full
was added with this commit
http://git.gnome.org/browse/glib/commit/?id=1d4009e6f7e1d368b3e3df2fa41b007277b600d8
between tags 2.31.4 and 2.31.6; as the patch description states,
it is a convenience method and fixes the bug
https://bugzilla.gnome.org/show_bug.cgi?id=657433

Best regards
Giovanni Gherdovich


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