cmp
is an expression with "function type". Expressions with these types are (almost) always implicitly converted to an expression with the corresponding function pointer type, similar (*see note at end) to how expressions with array type are implicitly converted to pointers to the first array element. This implicit conversion is often called decaying, though this is not a term used by the C language standard (but by C++).
&cmp
on the other hand makes the conversion explicit: Here you're taking the address of a function, thus receiving a function pointer.
So, bottom line: They're equivalent, and at least in C there's no practical difference between using one over the other.
The relevant part in the standard:
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]
Note: That means, being "explicit" all the times would mean writing function calls like this:
#include <stdio.h>
void foo(void) {
printf("Awesome\n");
}
int main() {
(&foo)();
return 0;
}
*) Important: The similarity mentioned is that there's an implicit conversion happening. While func
and &func
yield the exact same result (value and type), array
and &array
yield different results (different pointer types). The reason is that array
is implicitly converted to &(array[0])
. So, repeat, the similarity is that there are implicit conversions happening. The actual conversions are different.