75

Normally, when declaring some variable, you put its type before it, like:

int a;

a function pointer may have type like: int(*)(int,int), in case we point to a function that takes two integers and returns an integer. But, when declaring such a pointer, its identifier is not after the type, like:

int(*)(int,int) mypointer;

instead, you must write the identifier in the middle:

int(*mypointer)(int,int);

why is this so?

3
  • 3
    Search for "Declaration reflects use". Commented Jan 1, 2013 at 22:19
  • This Q helps explain Typedef syntax typedef old-type alias-identifier but example function pointer examples like "typedef int (*sum_func)(int,int);" don't match the syntax... Until now! Commented Sep 18, 2018 at 0:11
  • Because the language is badly designed. That's it! Commented Jul 26, 2022 at 16:12

4 Answers 4

43

I explain this in my answer to Why was the C syntax for arrays, pointers, and functions designed this way?, and it basically comes down to:

the language authors preferred to make the syntax variable-centric rather than type-centric. That is, they wanted a programmer to look at the declaration and think "if I write the expression *func(arg), that'll result in an int; if I write *arg[N] I'll have a float" rather than "func must be a pointer to a function taking this and returning that".

The C entry on Wikipedia claims that:

Ritchie's idea was to declare identifiers in contexts resembling their use: "declaration reflects use".

...citing p122 of K&R2.

Sign up to request clarification or add additional context in comments.

Comments

34

This structure reflects how a normal function is declared (and used).

Consider a normal function definition:

int foo (int bar, int baz, int quux);

Now consider defining a function pointer to a function of the same signature:

int (*foo) (int, int, int);

Notice how the two structures mirror each other? That makes *foo much easier to identify as a function pointer rather than as something else.

Comments

26

If you're dealing with a function (not a pointer to one), the name is in the middle too. It goes like: return-type function-name "(" argument-list ")" .... For example, in int foo(int), int is the return type, foo the name and int the argument list.

A pointer to a function works pretty much the same way -- return type, then name, then argument list. In this case, we have to add a * to make it a pointer, and (since the * for a pointer is prefix) a pair of parentheses to bind the * to the name instead of the return type. For example, int *foo(int) would mean a function named foo that takes an int parameter and returns a pointer to an int. To get the * bound to foo instead, we need parentheses, giving int (*foo)(int).

This gets particularly ugly when you need an array of pointers to functions. In such a case, most people find it easiest to use a typedef for the pointer type, then create an array of that type:

typedef int (*fptr)(int);

fptr array[10];

1 Comment

Best explanation of function pointer syntax I've seen. +1
12

I had seen at some places function pointers declared as

int (*foo) (int a, int b);

and at some places a and b are not mentioned and both still works.

so

int (*foo) (int, int)

is also correct.

A very simple way that I found to remember is as mentioned below:

Suppose function is declared as:

int function (int a , int b);

Step1: Simply put function in parentheses:

int (function) (int a , int b);

Step2: Place a * in front of function name and change the name:

int (*funcPntr) (int a , int b);

PS: I am not following proper coding guidelines for naming convention etc. in this answer.

2 Comments

Both int (*foo) (int a, int b); and int (*foo) (int, int); works because a parameter's name in a function prototype is optional in C.
How about using typedef in function pointer declaration?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.