Jono
Jono

Reputation: 223

C function pointers

static void increment(long long *n){
  (*n)++;
}

struct test{
  void (*work_fn)(long long *);
};

struct test t1;

t1.work_fn = increment;

How do I actually call the function now? t1.work_fn(&n) ?

Upvotes: 1

Views: 439

Answers (3)

AnT stands with Russia
AnT stands with Russia

Reputation: 320787

You can call it as t1.work_fn(&n) or as (*t1.work_fn)(&n), whichever you prefer.

Symmetrically, when assigning the pointer you can do either t1.work_fn = increment or t1.work_fn = &increment. Again, it is a matter of personal coding style.

One can probably argue that for the sake of consistency one should stick to either "minimalistic" style

t1.work_fn = increment;
t1.work_fn(&n);

or to a "maximalistic" style

t1.work_fn = &increment;
(*t1.work_fn)(&n);

but not a mix of the two, so that we can have well-defined holy wars between two distinctive camps instead of four.

P.S. Of course, the "minimalistic" style is the only proper one. And one must crack eggs on the pointy end.

Upvotes: 3

Michael Burr
Michael Burr

Reputation: 340516

How do I actually call the function now? t1.work_fn(&n) ?

That'll work just fine.

Function pointers don't need to be explicitly dereferenced. This is because even when calling a function normally (using the actual name of the function), you're really calling it through the pointer to the function. C99 6.5.22 "Function calls" says (emphasis mine):

The expression that denotes the called function (footnote 77) shall have type pointer to function returning void or returning an object type other than an array type

Footnote 77:

Most often, this is the result of converting an identifier that is a function designator.

Note that you still can dereference the function pointer (or a normal function name - though I think you'd cause much confusion doing so) to call a function because C99 6.5.3.2/4 "Address and indirection operators" says:

The unary * operator denotes indirection. If the operand points to a function, the result is a function designator

So all of these will end up doing the same thing (though the compiler might not be able to optimize the calls-through t1.work_fn as well):

t1.work_fn(&n);
(*t1.work_fn)(&n);

increment(&n);
(*increment)(&n);

Upvotes: 2

nmichaels
nmichaels

Reputation: 51039

Yes, that's how to call it. Function names and variables containing function pointers are essentially the same thing.

Upvotes: 0

Related Questions