Pointers to functions

Jun 5, 2013 at 8:49am
Hi, I'm at this part of the tutorial, in the section Pointers.
http://www.cplusplus.com/doc/tutorial/pointers/

"C++ allows operations with pointers to functions. The typical use of this is for passing a function as an argument to another function, since these cannot be passed dereferenced. In order to declare a pointer to a function we have to declare it like the prototype of the function except that the name of the function is enclosed between parentheses () and an asterisk (*) is inserted before the name:"

I perfectly understood how to declare a pointer to a function, what I did not was the highlited text...

What does it mean to pass a function as an argument to another function dereferenced?

Here is the code of the program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// pointer to functions
#include <iostream>
using namespace std;

int addition (int a, int b)
{ return (a+b); }

int subtraction (int a, int b)
{ return (a-b); }

int operation (int x, int y, int (*functocall)(int,int))
{
  int g;
  g = (*functocall)(x,y);
  return (g);
}

int main ()
{
  int m,n;
  int (*minus)(int,int) = subtraction;

  m = operation (7, 5, addition);
  n = operation (20, m, minus);
  cout <<n;
  return 0;
}
Last edited on Jun 5, 2013 at 8:53am
Jun 5, 2013 at 9:07am
You cannot pass function by-value (or by copy) so you have to pass pointer to memory area where function code is located.
Jun 5, 2013 at 9:13am
but in line 23 it passed "addition" as an argument and it isn't a pointer

or I didn't get it right (wich is more probable :)
Last edited on Jun 5, 2013 at 9:14am
Jun 5, 2013 at 9:20am
function name without function call operator () is a pointer to said function.
Jun 5, 2013 at 9:34am
so there "addition" is a pointer?

why create "minus" then?

thanks for the help though
Last edited on Jun 5, 2013 at 9:41am
Jun 5, 2013 at 9:47am
here I made a code that makes the same thing with no pointers,
the thing is what's the point about pointers to functions?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std;

int sum (int, int);
int sub (int, int);
int operation (int, int, int (int,int));

int main ()
{
    int s, r;
    s = operation (3,4,sum);
    r = operation (10,s,sub);
    cout << s << endl;
    cout << r << endl;

    return 0;
}

int sum (int a, int b)
{
    return a + b;
}

int sub (int a, int b)
{
    return a - b;
}

int operation (int a, int b, int f (int,int))
{
  return f(a,b);
}


and here an easy example of pointer to functions i just made

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// pointer to functions
#include <iostream>
using namespace std;

int addition (int, int);

int main ()
{
    int m;
    int (*sum) (int,int); // suma is a pointer to a function with two parameters (int, int)
    suma = addition;  // it points to the function addition

    cout << sum (1,2) << endl;
    cout << addition (1,2) << endl;
    return 0;
}

int addition (int a, int b)
{
    return a + b;
}
Jun 5, 2013 at 10:25am
here I made a code that makes the same thing with no pointers
It still uses pointers. sum & sub is a pointers in lines 11-12 context and f argument is a pointer too. Sometimes you might want to store info on which function you should call later. Or pass address of callback function.
You just not need it now, but it is a good idea to know what this is possible and how to do this.
Jun 5, 2013 at 10:31am
ok I understand now,

thank you very much for your help!
Jun 5, 2013 at 11:03am
one more question...

how would it be to pass a function as an argument to another function "dereferenced" or "by value"?

it would be something like this?

 
m = operation (7, 5, addition());


I know it's horrible, just want to check
Jun 5, 2013 at 1:17pm
No. m = operation (7, 5, addition()); would mean that the third argument to operation would be the return value from calling addition with no arguments.

If it were both meaningful and possible in C++, I would assume the syntax would be the same as for de-referencing any other type of pointer, i.e.

m = operation (7, 5, *addition);
Last edited on Jun 5, 2013 at 1:18pm
Jun 5, 2013 at 1:17pm
it would be *addition. However dereference operator essentually does nothing on function pointers (more info: http://stackoverflow.com/questions/2795575/how-does-dereferencing-of-a-function-pointer-happen )

Your example does function call (which is malformed because of insufficient operators)
Last edited on Jun 5, 2013 at 1:18pm
Jun 5, 2013 at 1:24pm
The trick with pointers to functions is to remember that the code is in memory somewhere. It may have a symbolic name that refers to it, like fopen. So it's possible to store and later use that address without that name.

Some functions are discovered at runtime and have no symbolic name. An example is where a shared library (or DLL in Windows) is loaded at runtime and functions are looked up. They don't have symbolic names, you can only hold their addresses in pointers.

It's analagous to not all variables having names. Dynamically allocated data on the heap doesn't have a symbolic name. You can only hold their addresses in pointers.

The extra catch is you need to keep track of the type so the compiler can check that you're using it correctly.

So for your example, I'd do this. Remember, when thing start getting complicated, typedef is your friend.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef int operation_t(int a, int b);

int operation(int a, int b, operation_t* op)
{
        return op(a, b);
}

int add(int a, int b)
{
        return a + b;
}

int sub(int a, int b)
{
        return a - b;
}

int main()
{
        int m = operation(7, 5, add);

        return 0;
}

Last edited on Jun 5, 2013 at 1:31pm
Jun 5, 2013 at 1:33pm
interesting... thanks everybody

btw
I was playing with functions pointers and tried to make a mix of function pointer and void pointer, but it's not working.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

void print()
{
    cout << "hello!" << endl;
}

void execute(void* f()) //receives the address of print
{
    void (*john)(); // declares pointer to function
    john = (void*)f; // assigns address of print to pointer, specifying print return
    john(); // execute pointer
}

int main()
{
    //print();
    execute(print); // function that sends the address of print
    return 0;
}


its based on this one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

void print();
void execute(void());

int main()
{
    execute(print);
    return 0;
}

void print()
{
    cout << "Hello!" << endl;
}

void execute(void f())
{
    f();
}
Last edited on Jun 5, 2013 at 2:01pm
Jun 5, 2013 at 2:05pm
john = f() It doesn't assigns pointer to function, it executes function and assigns result of execution (which is void and cannot be asssigned). Remember: () is a function call operator. If you don't want execution, do not use it.

Also: (void* f()) declares function returning void pointer. You should use either (void (*f)()) (Explicit declaration of function pointer) or (void f()) (Implicit one, does not reccomended)
Jun 5, 2013 at 2:09pm
so it's not possible then, I was trying to do the following but with functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

using namespace std;

void increase (void* address);

int main()
{
    int a = 10; // initializes a
    increase(&a); // function that sends the address of a
    cout << a << endl; // prints a
    return 0;
}

void increase (void* address) //receives the address of a
{
    int * p; // declares pointer
    p = (int*) address; // saves it in a pointer, specifying type
    *p = *p + 1; // increses a with the pointer
}
Jun 5, 2013 at 2:17pm
Function pointers cannot be cast. In fact there is no guarantees that two function pointers will have same representation or even size.

I still does not get what do you want to do, but anyway you are doing it wrong.
Jun 5, 2013 at 2:39pm
how would it be to pass a function as an argument to another function "dereferenced" or "by value"?

Dereferencing a pointer gives an lvalue, which you can pass as an argument to a function that expects a reference to function. Passing by value is indeed not possible, functions are not objects.
Topic archived. No new replies allowed.