0

Hi I am trying to do an array of function pointer and I have tried two things :

int (*pointer[2])(int, int); works perfectly

int (*pointer)[2](int, int); doesn't compile : "array element type cannot be function"

In my understanding the two should produce the same result, what can explain the difference ?

Thanks for your help

1
  • Look up the spiral rule. Commented Oct 29, 2013 at 2:03

2 Answers 2

5

C and C++ definitions like this have to be read from inside out. Starting from the name being defined, proceed to the right until you get to a closing paren, or the end of the declaration. After that, go back to the left from the previous stopping point until you get to an opening paren or the beginning of the declaration (after which you go back to the right again, and so on, until you've looked at the whole thing)1. With that in mind, let's consider your first declaration/definition:

int (*pointer[2])(int, int);

So, starting from pointer, we proceed right until we get to a closing paren, so we get as far as pointer is an array of 2, then we hit the paren, so we proceed to the left of pointer to get to the asterisk, so we add pointers, giving pointer is an array of two pointers. The we hit the open paren, so we proceed back to the right. We're now outside the parens, and we find the (int int), so we add "to functions taking two ints", and finally we proceed to the left again, and get "and returning int". So, our overall definition is "pointer is an array of two pointers to functions taking two ints and returning an int." That's fine and good, and the compiler accepts it as expected.

We follow the same idea with the second: int (*pointer)[2](int, int);

Here we hit the right paren immediately after pointer, so we go directly to pointer is a pointer, then we go outside that parens (and to the right) and get "to an array of 2". Then we keep proceeding right (we hit an open paren, not a close paren) and get "functions taking two ints". There we hit the end of the definition so we go back to the left and get the "and returning int". So, the overall definition is: "pointer is a pointer to an array of two functions taking two ints as parameters and returning an int."

Since we can't have arrays of functions, this gives an error.


1. Some people come up with names like "spiral rule", "clockwise rule", and so on for this, but I find the names more misleading than helpful. Most get caught up in their own "cuteness", and forget to clearly enunciate the real rules about when to stop proceeding one direction, and start looking the other direction again.

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

3 Comments

Great answer. I left mine because I want to know whether it's still wrong.
@Elazar: Much closer anyway. Technically, the second is still wrong though (fs is a pointer to an array...)
Well I can't seem to get it right. How can I combine the last two examples in one declaration (assuming it's not an error to do so)?
0

Always use typedef with function pointers. This is the easiest way.

typedef int (*func_ptr)(int, int);
typedef func_ptr fps[2];

fps is a type of array of pointers to functions.

Your second example is like doing this:

typedef int func(int, int); // legal! defines a function type. not a pointer.
typedef func fs[2];        // Illegal: an array of function.

typedef fs* pfs;            // The type you tried to get:
                            // A pointer to an array of functions.

You get an error: "declaration of ‘fs’ as array of functions".

3 Comments

Can't upvote this as you're not actually answering the question: "what can explain the difference"?
@j_random_hacker Still?
After you fix the pointer thing, you need to write about how typenames are parsed using precedence rules. That's the underlying problem with the OP's snippet #2.

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.