这个函数指针在这里发生了什么

What is happening here with this function pointer

我有一个函数正在传递给另一个函数,但我不确定为什么这两个函数都有效并且没有产生任何警告。

typedef short (*COMP)(char  *, char *);

DATA *bst_get(BST *, char *, COMP);

short cmp(char *a, char *b)
{
    if (strstr(a, b))
        return 0;
    return strcmp(a, b);
}

// Both of these produce the same results
//     the difference is '&cmp' vs 'cmp'
data = bst_get(bst, "textA", &cmp);
data = bst_get(bst, "textA", cmp);

那么正确的用法是什么?重要吗?

在 C 中,函数在表达式中使用时会转换为指向函数的指针。
这里的cmp&cmp都表示函数的地址,因此都相当于bst_get的函数参数。

cmp是带"function type"的表达式。具有这些类型的表达式(几乎)总是隐式转换为具有相应函数 pointer 类型的表达式,similar(*见末尾的注释)到数组类型的表达式如何隐式转换为指向第一个数组元素的指针。这种隐式转换通常称为 decaying,尽管这不是 C 语言标准(而是 C++)使用的术语。

另一方面,

&cmp 使转换显式:在这里您获取函数的地址,从而接收函数指针。

所以,底线是:它们是等价的,至少在 C 语言中,两者之间没有实际区别。

标准中的相关部分:

A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".

[N1570 §6.3.2.1/4]

注意:这意味着,一直 "explicit" 将意味着像这样编写函数调用:

#include <stdio.h>

void foo(void) {
  printf("Awesome\n");
}

int main() {
  (&foo)();
  return 0;
}

*) 重要:提到的相似之处在于发生了隐式转换。虽然 func&func 产生 完全相同的 结果(值和类型),但 array&array 产生 不同的 结果(不同的指针类型)。原因是array被隐式转换为&(array[0])。所以,重复一遍,相似之处在于发生了隐式转换。实际转换不同。