c - 为什么函数指针声明需要知道参数和返回值的类型?

标签 c pointers compiler-construction function-pointers static-typing

为什么 C 中的函数声明需要知道指向函数的参数和返回值的类型?

c中的一个指针声明是这样写的:

returnType ( *funcPtrName ) ( paramTypes )

例如下面的foo:

char my_func ( int x )
{
    ...
}


int main ()
{
    char ( *foo ) ( int );

    foo = my_func;

    foo( 2 );
}

当声明一个指向值的指针时,类型用于确定一个元素的大小(以字节为单位)。例如在 int* p 中,int 告诉编译器 p 指向的元素是 sizeof( int )分开。此信息用于指针运算。

但是,函数指针指向单个地址并且不允许进行指针运算。

那么为什么需要额外的信息呢? returnTypeparamTypes 是否仅用于支持编译器的错误检查? (例如,当用户分配类型不匹配的函数时提醒用户)。

最佳答案

有几个原因。让我们先考虑返回值。

假设一个程序包含代码y = f(x);。调用f后,编译器需要获取它返回的值并将其赋值给y。它从哪里获得这个值(value)?在某些系统中,整数返回值在通用寄存器中传递,浮点返回值在浮点寄存器中传递。所以编译器无法知道返回值在哪里,除非它知道类型。宽整数,例如 long long int,可能会在多个寄存器中传递。小结构可能会在寄存器中返回,而大结构可能会在内存中返回,使用指向调用函数提供的空间的指针,并且需要将其作为隐藏参数传递给被调用函数。

同样,编译器在调用函数时需要知道将参数放在哪里。前几个整数参数可能在通用寄存器中传递,而前几个浮点参数可能在浮点寄存器中传递。任何一种类型的附加参数都可能被压入堆栈。

此外,有时程序员可能会在函数实际需要浮点参数的地方传递一个整数表达式,例如在 pow(x, 4) 中。当编译器知道参数必须是浮点参数时,它可以将其转换为预期的类型。

另一个好处是,当编译器知道类型时,如果参数与预期类型不匹配并且不能隐式转换为预期类型,它可以报告错误,如果返回类型同样可以报告错误不匹配。

关于c - 为什么函数指针声明需要知道参数和返回值的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57263009/

相关文章:

c - 使用 fork() 显示进程树

c - 如何在 C 中调用 system() 来执行日期命令

c++ - 交换基本类型的对象会抛出异常吗?

我可以通过 char* 指针访问 int 变量的每个字节吗?

c - 共享库如何减少进程(数据、代码等)使用的空间?

c++ - 在 C++ 中创建一个只有用户可以查看和编辑该文件的权限的文件

c - 如何通过 gets() 函数将用户输入作为十六进制字符? (Linux)

char 数组末尾包含垃圾

javascript - 如何用 Peg.js 打开文件?

compiler-construction - 编译器级别的分支预测