Raulp
Raulp

Reputation: 8136

Difference between these two confusing function pointer notations in C?

What is the difference between these two function pointer notations in C?

void (*a[]()) and void (*a)()[]

Do they both represent same - a as an array of pointers to functions - or does the second one represent a pointer to an array of functions?

How should I call these functions - say void (*a[]()) = {swap, add, sub, prod};?

Does that mean that a is an array of function pointers of 4 elements and swap, add, sub, prod's address are there in the a[0]...a[3]. How should I invoke these functions, like this?

*a[i]()

or like this?

a[i]()

Upvotes: 2

Views: 1907

Answers (4)

glglgl
glglgl

Reputation: 91017

According to the Right-Left-Rule in C (other reference here), both expressions are considered invalid by the compiler (and probably by the standard as well).

The first one is a array of functions, the latter is an array of voids.

An array of pointers to functions returning void would be

void (*a[])()

.

Upvotes: 4

John Bode
John Bode

Reputation: 123448

They're both invalid.

void (*a[]());

is interpreted as

       a        -- a
       a[]      -- is an array
       a[]()    -- of function
      *a[]()    -- returning pointer
void (*a[]())   -- to void.

You cannot declare an array of function type. Similarly,

void (*a)()[]

is interpreted as

       a       -- a
     (*a)      -- is a pointer
     (*a)()    -- to a function
     (*a)()[]  -- returning an array of unknown size
void (*a)()[]  -- of void.

Functions cannot return array types, and you can't have arrays of void.

If you want to declare an array of pointers to functions returning void, you'd build it up as:

       a          -- a
       a[N]       -- is an N-element array
      *a[N]       -- of pointers
     (*a[N])()    -- to functions
void (*a[N])();   -- returning void

Thus, void (*a[N])(); declares a as an array of pointers to functions returning void. You'd call each individual function in the array as

(*a[i])();

or

a[i]();

although I prefer the first form, even if it is a little more cluttered.

So, given the list of functions swap, add, sub, and prod, you'd build up your array as

void swap() {...}
void add() {...}
void sub() {...}
void prod() {...}
...
void (*a[])() = {swap, add, sub, prod};
...
(*a[0])(); // calls swap
(*a[1])(); // calls add

Given the function names, I assume they take some kind of arguments. Note that all the function pointers in an array should have the same signature; that is, they should all have the same return type, as well as the same number and types of arguments.

When you call a function through a pointer, C allows you to drop the explicit dereference, so you could call those functions as

 a[0]();
 a[1]();

but I prefer the first form, even if it is visually more cluttered.

Remember that [] and function-call () have higher precedence than unary *, so T *a[N] declares an N-element array of pointer to T, T (*a)[N] declares a pointer to an N-element array of T, T *f() declares a function returning a pointer to T, and T (*f)() declares a pointer to a function returning T.

Upvotes: 5

Jens Gustedt
Jens Gustedt

Reputation: 78903

The second expression is not valid in C, since first it doesn't allow for arrays of void and second it doesn't allow a function to return an array.

Upvotes: 0

Mahmoud Al-Qudsi
Mahmoud Al-Qudsi

Reputation: 29519

Use cdecl.org to figure this stuff out until you can do it without thinking about it.

void (*a[]()): declare a as array of function returning pointer to void

whereas

void (*a)()[]: declare a as pointer to function returning array of void

The latter is invalid C.

Upvotes: 6

Related Questions