sle*_*ske 10 c pointers casting function-pointers type-safety
我刚刚开始围绕C中的函数指针.要了解函数指针的转换是如何工作的,我编写了以下程序.它基本上创建了一个函数指针,该函数指向一个带有一个参数的函数,将它转换为带有三个参数的函数指针,并调用该函数,提供三个参数.我很好奇会发生什么:
#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;
}
Run Code Online (Sandbox Code Playgroud)
这编译并运行时没有错误或警告(在Linux/x86上为gcc -Wall).我系统的输出是:
Call function with parameters 2,4,8.
Result: 4
Run Code Online (Sandbox Code Playgroud)
显然,多余的论点只是默默地被抛弃了.
现在我想了解这里发生了什么.
我来自Java,那里的类型检查要严格得多,所以这种行为让我有点困惑.也许我正在经历文化冲击:-).
Fra*_*nov 15
额外的参数不会被丢弃.它们被正确放置在堆栈上,就像调用需要三个参数的函数一样.但是,由于您的函数仅关注一个参数,因此它仅查看堆栈顶部并且不会触及其他参数.
基于以下两个事实,这个呼叫有效的事实是纯粹的运气:
编译器无法通过一个简单的原因警告您这样的潜在问题 - 在一般情况下,它在编译时不知道指针的值,因此它无法评估它指向的内容.想象一下,函数指针指向在运行时创建的类虚拟表中的方法?所以,你告诉编译器它是一个指向具有三个参数的函数的指针,编译器会相信你.