Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer to function parameter vs function parameter?

Tags:

c++

pointers

I'd like to understand what is the difference between the 2 declarations, f1 and f2, below: In f1 I declare the parameter to be a pointer to a function of type void(), how is the f2 declaration different from the f1? Are the declarations equivalent? In main I can invoke both of them with functions of prototype void (). I understand the concept of passing by value/pointer/reference, however these are functions and don't really understand the difference. It is not like I can "modify" the function passed as parameter in f1... Thanks!

PS: came by this question when bumping into the well known Most Vexing Parsing problem :)

#include <iostream>

using namespace std;

void f1(void (*x)())
{
    x();
}

void f2(void x())
{
    x();
}

void g1()
{
    cout << "Invoking f1(g1())" << endl;
}

void g2()
{
    cout << "Invoking f2(g2())" << endl;
}


int main() 
{
    f1(g1);
    f2(g2);
}

The program compiles and the output is

Invoking f1(g1())
Invoking f2(g2())
like image 467
vsoftco Avatar asked May 24 '14 01:05

vsoftco


2 Answers

They're equivalent. You're getting confused by the implicit pointer conversion that happens with arguments.

Since you can't pass a function as an argument to a function (you can't do anything with functions in C other than call them or take their address), the compiler silently changes the argument into a pointer to a function.

This is much the same as happens with arrays -- you can't pass arrays as function arguments either, so any time you declare a function argument as an array, it silently gets changed into a pointer.

like image 29
Chris Dodd Avatar answered Oct 24 '22 22:10

Chris Dodd


In both C and C++, if you declare a function parameter to have function type, its type will be adjusted to function pointer.

C99, §6.7.5.3/8

A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1.

C++11, §8.3.5/5

... After determining the type of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively...

Thus, in C++, for example, we can write the types of both f1 and f2 as void(void(*)()).

like image 62
Brian Bi Avatar answered Oct 24 '22 22:10

Brian Bi