分配函数指针的正确方法

我对将函数指针赋给变量的正确语法感到困惑。 如果我有一个函数foo

int foo(); 

我正在将指向foo的指针分配给变量栏

 void * bar; 

如果我使用它似乎没关系

 bar = foo; // or bar = &foo; 

在我看来,这些中只有一个应该是正确的还是我错过了什么?

foo&foo值在C中是等价的,并且具有相同的类型。

&运营商在这里是正确但多余的。

请注意,将函数指针指定给void *在C中无效。

 void *fp1 = foo; // invalid int (*fp2)() = foo; // valid int (*fp3)() = &foo; // valid 

(这些实际上是声明,但赋值运算符的约束适用。)

让我解释一下。

foo和&foo值在C中是等价的,并且具有相同的类型。

正如@ouah对答案的评论所指出的那样,这并不完全正确。 尤其:

  1. sizeof(foo)无效, sizeof(&foo)是指针的大小。
  2. &foo&foo的指针,而&(&foo)无效。

但是,它们在所有其他情况下实际上是相同的,正如C标准所提到的那样(参考例如C11草案 ):

6.3.2.1.4:函数指示符是具有函数类型的表达式。 除非它是sizeof运算符或一元&运算符的操作数,否则将具有“函数返回类型”类型的函数指示符转换为具有“指向函数返回类型的指针”类型的表达式

当函数指示符未转换为指针时, sizeof和一元&运算符是唯一的两个例外。

PS你也可以找到为什么sizeof(foo)&(&foo)无效:

6.5.3.2.1:一元&运算符的操作数应该是函数指示符, []或一元*运算符的结果,或者是一个左值,它指定一个不是位字段且未声明的对象寄存器存储类指定器。

6.5.3.4.1 sizeof运算符不应应用于具有函数类型或不完整类型的表达式,应用于此类型的带括号的名称,或应用于指定位字段成员的表达式。