5

I'm trying to call a function that takes an argument, void(*)(void*, int, const char*), but I cannot figure out how to pass those arguments to the function.

Example:

void ptr(int);
int function(int, int, void(*)(int));

I am trying to call the function like this:

function(20, 20, ptr(20));

Is this possible?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bryan sammon
  • 7,161
  • 15
  • 38
  • 48
  • Thanks alot everyone, I figured it out. I learned alot about pointers to functions from this question. Again, thanks alot! – bryan sammon Feb 04 '12 at 19:28

6 Answers6

9

You are doing one thing incorrectly - you are trying to invoke your 'ptr' function before invoking 'function'. What you were supposed to do is to pass just a pointer to 'ptr' and invoke 'ptr' using passed pointer from 'function' like that:

void ptr(int x)
{
    printf("from ptr [%d]\n", x);
}

int function(int a, int b , void (*func)(int) )
{
    printf( "from function a=[%d] b=[%d]\n", a, b );
    func(a); // you must invoke function here

    return 123;
}


void main()
{
    function( 10, 2, &ptr );
    // or
    function( 20, 2, ptr );
}

which gives:

from function a=[10] b=[2]
from ptr [10]
from function a=[20] b=[2]
from ptr [20]

which is what you wanted

for

function(20, 20, ptr(20));

to work - you would have to have sth like:

// 'ptr' must return sth (int for example)
// if you want its ret val to be passed as arg to 'function'
// this way you do not have to invoke 'ptr' from within 'function'
int ptr(int);
int function(int, int , int);
Artur
  • 7,038
  • 2
  • 25
  • 39
4

The usual trick is to use a typedef for signature:

 typedef void signature_t (void*, int, const char*);

Notice that without the typedef the syntax is like a function declaration. It declares signature_t as a typedef for functions, so you'll always use pointers to signature_t in practice.

Then you can declare your "high-order" function as

 int function (int, int, signature_t*);

See also this reply.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 3
    Isn't correct syntax for that `typedef void (signature_t)( void*, int, const char*)`? Anyway +1 for `typedef` idea :) – Vyktor Feb 04 '12 at 18:47
  • 1
    @Vyktor: Parentheses are not needed here. The syntax in the answer is correct. – jpalecek Feb 04 '12 at 19:07
1

The correct syntax for function call is:

function(20,20, &ptr);

If you feel lost, try some tutorials, or this

Vyktor
  • 20,559
  • 6
  • 64
  • 96
  • 4
    You can actually leave the `&` off if you want – Seth Carnegie Feb 04 '12 at 18:47
  • @SethCarnegie what compiler are you referring to? As far as I remember gcc wan't very friendly with this. Anyway it feels more obvious what are you trying to say when you add `&` (my opinion). – Vyktor Feb 04 '12 at 18:49
  • 1
    gcc handles that (not putting the `&`) just fine, and its standard C. – Mat Feb 04 '12 at 18:50
  • @Mat thanks for explaining, I was working for the first time with Qt than and this was just one of may things that I had problem with... But using `&` is correct, right? Or is it against standards? Lets make perfect code out of this :) – Vyktor Feb 04 '12 at 18:54
  • 1
    @Vyktor: According to the standard, `ptr == &ptr == *ptr == **ptr == ***ptr = ...` Since `ptr` is shortest and very clear, many prefer it. – Dietrich Epp Feb 04 '12 at 19:00
1

Unless I totally misinterpret your code, you are trying to pass a function pointer with an argument by doing

function(20, 20, ptr(20));

That is incorrect and illegal. In order to pass a function as a parameter into another function you have to follow the following syntax

function(20, 20, &ptr); 

or

function(20, 20, ptr); 

Even though I would recomment leaving the '&' for readability

Lefteris
  • 3,196
  • 5
  • 31
  • 52
0

You can't pass ptr(20) to this function, because you can only pass the pointer to the function but not the pointer with the argument. You may read about functors and theu will help you with such problem. Or the other solution is to change the signature to

int function(int, int, void(*)(void) );

And write function

void ptr_wrap(void) {ptr(20);}

so you can call function(20, 20, ptr_wrap);. But functors can solve this problem in more elegant way.

Seagull
  • 3,319
  • 2
  • 31
  • 37
0

ptr(20) is the return value of ptr, when you pass 20 to it. If you want to pass the function (and not its return value), you should write just function(20,20,ptr);

asaelr
  • 5,438
  • 1
  • 16
  • 22