2

I have the following program:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int my_init(size_t n);

int
my_init(size_t n) { return (int) n; }

int
main(void)
{
  int (*init)(size_t n);

  init = &my_init;

  return 0;
}

and my question is how to correctly assign the function pointer init. Is it correct to say:

init = &my_init;

or

init = my_init;

Both seem to pass gcc with strict warnings:

gcc -ansi -pedantic -Werror -W -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -fshort-enums -fno-common -Wmissing-prototypes -Wnested-externs -Dinline= -g

So which is correct? I even used the lint checker splint on both versions, and got no warnings in either case.

4 Answers4

1

Both are correct and equivalent as per the C Standard: C99, 6.5.3.2#3 (emphasis mine)

3 The unary & operator returns the address of its operand. If the operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator. Otherwise, the result is a pointer to the object or function designated by its operand

We have a coding guideline at work (rocket science), where we require the & form for function pointer assignments, to make it clear we haven't just forgotten the parentheses.

Jens
  • 69,818
  • 15
  • 125
  • 179
1

You don't have to use the &, but it improves readability, so I recommend using it.

kol
  • 27,881
  • 12
  • 83
  • 120
  • That's very debatable. Also, means you cannot substitute a variable without causing errors. – Deduplicator Apr 09 '14 at 19:54
  • 1
    @Deduplicator I'd say it's not debatable. If you need to replace a function pointer with an object pointer, the types don't match and you'd have to edit each place anyway. And the compiler even tells you about type mismatches. But maybe I misunderstood. Could you be more specific where the problem with `&` for function pointers is? – Jens Apr 09 '14 at 19:59
  • @Jens: Added my own answer, making clear that `&`is only allowed for historical reasons and not using it allows treating pointers and function designators interchangeable for all but assigning to them. – Deduplicator Apr 09 '14 at 20:06
1

Both would be correct. From there, you can simply call it as such:

int init_return = (*init)(3);

EDIT: As correctly pointer out by Steve, you can also just do:

int init_return = init(3);

Both would be equivalent.

wyas
  • 377
  • 2
  • 14
0

Using & on a function name has no effect for historical reasons.
For those same reasons, you can dereference a function pointer (constant) any number of times, without effect.

Not using a redundant & for getting the function address is preferable, because it makes treating function designators and function pointer variables interchangeably easier. No need for you to know which you have, as long as you only want to call it/assign it to a pointer/pass it.

Also, how many redundant dereferences or address of operations are enough? I opt for 0 and cleaner code.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118