首页 > 解决方案 > 为什么函数指针声明需要知道参数和返回值的类型?

问题描述

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

c 中的指针声明如下所示:

returnType ( *funcPtrName ) ( paramTypes )

例如foo下面:

char my_func ( int x )
{
    ...
}


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

    foo = my_func;

    foo( 2 );
}

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

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

那么为什么需要额外的信息呢?returnType包含和paramTypes仅仅是为了支持编译器的错误检查吗?(例如,在用户分配类型不匹配的函数时提醒用户)。

标签: cpointerscompiler-constructionfunction-pointersstatic-typing

解决方案


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

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

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

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

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


推荐阅读