Can you cast a function pointer of this type:
void (*one)(int a)
to one of this type:
void (*two)(int a, int b)
and then safely invoke the pointed-to function with the additional arguments(s) it has been cast to take? I had thought such a thing was illegal, that both function types had to be compatible. (Meaning the same prototype--same return value, same parameter list.) But that is exactly what this bit of GTK+ code appears to be doing (taken from here):
g_signal_connect_swapped(G_OBJECT(button), "clicked",
G_CALLBACK(gtk_widget_destroy), G_OBJECT(window));
If you look up the "clicked" signal (or just look at other examples of its use from the first link), you will see that its handlers are expected to be declared like this:
void user_function(GtkButton *button, gpointer user_data);
When you register a handler via g_signal_connect_swapped(), the widget pointer and data pointer arguments are swapped in order, thus, the declaration should look like this instead:
void user_function(gpointer user_data, GtkButton *button);
Here is the problem. The gtk_widget_destroy() function registered as a callback is prototyped like this:
void gtk_widget_destroy(GtkWidget *widget);
to take only a single argument. Presumably, because the data pointer (a GtkWindow) and the pointer to the signaling widget (a GtkButton) are swapped, the sole argument it receives will be the window pointer, and the button pointer, which will be passed after, will silently be ignored. Some Googling has turned up similar examples, even the registering of functions like gtk_main_quit() that take no arguments at all.
Am I correct in believing this to be a standards violation? Have the GTK+ developers found some legal magic to make this all work?