Tôi chỉ mới bắt đầu quấn đầu quanh các con trỏ hàm trong C. Để hiểu cách truyền con trỏ hàm hoạt động, tôi đã viết chương trình sau đây. Về cơ bản nó tạo ra một con trỏ hàm tới một hàm lấy một tham số, đưa nó tới một con trỏ hàm với ba tham số và gọi hàm, cung cấp ba tham số. Tôi đã tò mò điều gì sẽ xảy ra:Điều gì sẽ xảy ra nếu tôi gán con trỏ hàm, thay đổi số tham số
#include <stdio.h>
int square(int val){
return val*val;
}
void printit(void* ptr){
int (*fptr)(int,int,int) = (int (*)(int,int,int)) (ptr);
printf("Call function with parameters 2,4,8.\n");
printf("Result: %d\n", fptr(2,4,8));
}
int main(void)
{
printit(square);
return 0;
}
Việc biên dịch và chạy mà không có lỗi hoặc cảnh báo (gcc -Wall trên Linux/x86). Kết quả đầu ra trên hệ thống của tôi là:
Call function with parameters 2,4,8.
Result: 4
Vì vậy, dường như các đối số thừa được bỏ qua một cách đơn giản.
Bây giờ tôi muốn hiểu điều gì đang thực sự xảy ra ở đây.
- Tính hợp pháp: Nếu tôi hiểu câu trả lời cho Casting a function pointer to another type chính xác, đây chỉ là hành vi không xác định. Vì vậy, thực tế là điều này chạy và tạo ra một kết quả hợp lý chỉ là may mắn tinh khiết, đúng không? (hoặc độc đáo trên một phần của các nhà biên dịch biên dịch)
- Tại sao gcc không cảnh báo tôi về điều này, ngay cả với Tường? Đây có phải là một cái gì đó trình biên dịch chỉ không thể phát hiện? Tại sao?
Tôi đến từ Java, nơi kỹ thuật đánh máy là rất chặt chẽ hơn, vì vậy hành vi này làm tôi bối rối một chút. Có lẽ tôi đang trải qua một cú sốc văn hóa :-).
Nếu điều đó đã là một cú sốc văn hóa cho bạn, hãy chờ cho đến khi bạn phát hiện ra rằng trong C++ con trỏ đến các hàm thành viên có thể lớn hơn void *, mặc dù chúng không mang con trỏ này với chúng ... – OregonGhost