Tôi liên tục gặp vấn đề thiết lập bộ xử lý tín hiệu trong mã GTK +, không cần một số thông số và bị cám dỗ để sử dụng cùng chức năng với trình xử lý cho một số tín hiệu. đối số (những cái tôi quan tâm) giống nhau. Có phải là an toàn (theo nghĩa là nó không phải là hành vi không xác định, thay vì ý nghĩa thực dụng hơn về "nó hoạt động trên PC của tôi?") Để chuyển con trỏ tới các hàm với API GObject khi các hàm đó có ít hơn đối số hơn là chúng thực sự sẽ nhận được từ quá trình phát tín hiệu?Có an toàn khi gọi hàm C với nhiều đối số hơn dự kiến không?
Hoặc, để ly dị điều này khỏi GTK +, mã này có được không?
/* Note: No void *userdata argument! */
void show(int x) {
printf("x = %d\n", x);
}
void do_stuff(void (*fn)(int, void *), void *userdata) {
static int total = 0;
(*fn)(total, userdata);
total++;
}
void doitnow(void) {
do_stuff(&show, NULL);
}
Để biết thêm tín dụng, hãy thảo luận về ý nghĩa của các loại giá trị trả lại khác nhau giữa chữ ký chức năng và trang web cuộc gọi.
Chỉnh sửa: An almost-identical question đầu dò "loại chức năng tương thích" chặt chẽ hơn và rút ra an answer directly addressing my concrete problem - điều khiển chuỗi xử lý tín hiệu GObject. TL; DR: Có, đó là hành vi không xác định, nhưng thực tế là thành ngữ (mặc dù không bắt buộc) trong một số bộ công cụ.
Tôi gần như chắc chắn rằng việc chuyển đổi con trỏ hàm theo cách đó là UB. – Flexo
@Flexo Chuyển đổi con trỏ hàm là không sao. Sử dụng nó cho bất cứ điều gì khác hơn là chuyển đổi trở lại, mặt khác, ... –
BTW, không cần '(* fn)' trong do_stuff. Chỉ cần gọi 'fn (total, userdata)'. Vì 'fn' là một con trỏ hàm, toán tử gọi hàm' (total, userdata) 'thực hiện chính xác những gì bạn mong đợi. – Jens