I just can not figure out the signatures of callback functions that are associated with certain signals.

At first I thought that each type of event has its own function signature, but after digging in various sources, I met different types of functions for the same signals.

Then I tried changing the signatures - I added parameters of different types to the function ...

And no warnings or failures have arisen.

How does this magic work?

Ps. Here is an example of the code that was requested in the comments:

#include <stdio.h> #include <stdlib.h> #include <gtk/gtk.h> void func_1(void) { abort(); } gint func_2(void) { abort(); return 1; } // _int и _data можно менять местами, GTK при помощи какой-то магии // использует _data правильно. // Плюс, параметра _int вообще не должно быть среди параметров функции. gboolean func_3(GtkWidget *_widget, gint _int, gpointer _data) { gtk_button_set_label(GTK_BUTTON(_widget), _data); return TRUE; } int main(int argc, char **argv) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *button = gtk_button_new_with_label("magic"); gtk_container_add(GTK_CONTAINER(window), button); //g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(func_1), NULL); //g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(func_2), NULL); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(func_3), "reset"); gtk_widget_show_all(window); gtk_main(); return 0; } 

There are no mistakes. All three callback options work correctly.

The third variant of the function works even under the condition that the return value is not void, but the left argument is in the position in the argument list of the function.

  • This magic is called define. You can easily override everything. - Yaroslav
  • How are signatures and signals combined? 8) it is round and green .. Give an example of what you described .. And the signature is a function declaration? - NewView
  • @Yaroslav, how to define solves the problem of inconsistency of the function signature? How does a function that accepts a pointer to a callback function deal with what the types of parameters of the callback function really are, what is their number and order? - user294535
  • Show the code in which you have "no warnings or failures have occurred." Something hard to believe. If this is true, then show the definition of these macros from your GTK. - AnT
  • one
    gtk_signal_connect is a deprecated function and should not be used anymore. - AnT

1 answer 1

Your code uses the G_CALLBACK macro, which internally performs a forceful explicit cast of the type of any pointer to a function to the “correct” type of GCallback (that is, to void (*) (void) ). Not surprisingly, the compiler does not swear.

Since different variants of callbacks for different signals require different types of functions, the authors of the API had no other choice but to bring all types of callbacks to one common “universal” type. A side effect of this technique is the complete loss of diagnosis from the compiler.

In this case, the void (*) (void) in the context of function pointers is used in the same role as the void * type for data pointers, i.e. as a "pointer to anything."

In such a situation, it is up to you to monitor the accuracy of callbacks provided. Provide incorrect - behavior will be undefined.

  • I understand all this, but in my example the third variant of the function is processed correctly, no matter what parameters we put there, and in what order. But the order of the parameters of the function on the stack also depends on the calling agreement. Plus, I don’t quite understand how in this case the compiler controls the insertion of function parameters onto the stack and clearing the stack ... - user294535
  • 2
    @ Maxim It seemed to you that everything is being worked out correctly. Behavior is not defined. Indefinite behavior may look "correct" at first glance. And why did you think that the parameters are "on the stack"? Passing parameters through the stack is already a mossy rarity. - AnT
  • Well, I assumed it was UB. Just this is given in the examples for studying GTK. Very strange looking and confusing ... - user294535
  • But I did not understand, does each signal have its own signature for the callback function? And where can I see how the function signature should look like to communicate with a signal? - user294535
  • @ Maxim UB is exactly your way of exchanging the "wrong" functions as callbacks. Where did you see this in the study examples? If the function is substituted, then there is no UB. And how the correct function should look for each signal can be found in the documentation: developer.gnome.org/gtk3/stable/GtkButton.html . See Signals section. - AnT