Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit cast from function to function pointer?

I have a function that accepts as an argument a function pointer. Surprisingly, I can pass in both a function pointer and an ordinary function:

#include <iostream>
#include <functional>

int triple(int a) {
    return 3*a;
}

int apply(int (*f)(int), int n) {
    return f(n);
}

int main() {
    std::cout << apply(triple, 7) << "\n";
    std::cout << apply(&triple, 7) << "\n";
}

I'm confused about why this works. Is there an implicit conversion from functions to function pointers?

like image 408
rampatowl Avatar asked Jan 25 '19 01:01

rampatowl


People also ask

Why pointer convert from one type to another is prohibited in C?

Conversion of an integer into a pointer to a function is also permitted by The Standard. However, both are prohibited by this rule in order to avoid the undefined behaviour that would result from calling a function using an incompatible pointer type.

What is an implicit conversion?

An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.

Can you cast a function pointer?

Yes, it can. This is purpose of casting function pointers, just like usual pointers. We can cast a function pointer to another function pointer type but cannot call a function using casted pointer if the function pointer is not compatible with the function to be called.


1 Answers

Yes, there's function-to-pointer implicit conversion:

An lvalue of function type T can be implicitly converted to a prvalue pointer to that function. This does not apply to non-static member functions because lvalues that refer to non-static member functions do not exist.

And

A pointer to function can be initialized with an address of a non-member function or a static member function. Because of the function-to-pointer implicit conversion, the address-of operator is optional:

void f(int);
void (*p1)(int) = &f;
void (*p2)(int) = f; // same as &f

That means when being used in context requiring a function pointer, function (except for non-static member function) would convert to function pointer implicitly, and the usage of operator& is optional.

like image 158
songyuanyao Avatar answered Oct 03 '22 05:10

songyuanyao