I am having difficulty trying to understand what the following declaration means. Is this declaration standard?
double* (*p[3]) (void* (*)());
Can anyone help me to understand the meaning of this declaration?
Rule for reading hairy declarations: find the leftmost identifier and work outward, remembering that () and [] bind before *, so T *a[N] is an array of pointers to T, T (*a)[N] is a pointer to an array of T, T *f() is a function returning a pointer to T, and T (*f)() is a pointer to a function returning T. Since a function prototype may omit parameter names, you may see things like T *[N] or T (*)(). The meaning is mostly the same1, just pretend that there's an identifier of 0 length.
Thus,
p -- p
p[3] -- is a 3-element array
*p[3] -- of pointers
(*p[3]) ( ) -- to functions
(*p[3]) ( (*)()) -- taking a pointer to a function
(*p[3]) ( * (*)()) -- returning a pointer
(*p[3]) (void* (*)()) -- to void
* (*p[3]) (void* (*)()) -- returning a pointer
double* (*p[3]) (void* (*)()); -- to double
The important thing to take away here is that you are declaring p as an array of ..., not a function returning ....
What would such a beast look like in practice? Well, first, you need three functions to point to. Each of these functions takes a single parameter, which is a pointer to a function returning a pointer to void:
double *foo(void *(*)());
double *bar(void *(*)());
double *bletch(void *(*)());
double *(*p[3]) (void *(*)()) = {foo, bar, bletch};
Each of foo, bar, and bletch would call the function passed to it and somehow return a pointer to double.
You would also want to define one or more functions that satisfy the parameter type for each of foo, bar, and bletch:
void *blurga() {...}
so if you called foo directly, you'd call it like
double *pv;
...
pv = foo(blurga);
So we could imagine a call like
double *pv = (*p[0])(blurga);
1 - the difference is that in the context of a function parameter declaration, T a[] and T a[N] are identical to T *a; in all three cases, a is a pointer to T, not an array of T. Note that this is only true in a function parameter declaration. Thus, T *[] will be identical to T **.
Just use http://cdecl.org:
declare p as array 3 of pointer to function (pointer to function returning pointer to void) returning pointer to double
For more info, see this MSDN article: Interpreting more complex declarators.
But typedefs would help:
typedef void *(*foo)(); // foo is a function-pointer type
typedef double *(*bar)(foo); // bar is also a function-pointer type
bar p[3];
(Obviously, use appropriate names in place of foo and bar!)
Your p is an array of 3 pointers to a function returning a double pointer, and taking as argument a pointer to another function that returns a void pointer and that takes no arguments.
But, don't use this syntax, try using typedef instead.
It is array (of size 3) of function pointers which returns pointer to double and take another function pointer as argument.
Type of function whose pointer can be stored in the array: double *(func)(void* (*)())
Type of function whose pointer can be passed as argument to func: void *(func1)(void)
"There is a technique known as the ``Clockwise/Spiral Rule'' which enables any C programmer to parse in their head any C declaration!"
Clockwise Spiral Rule - http://c-faq.com/decl/spiral.anderson.html
Related
How can I pass the location of an array of pointers in a function in c i.e.
I have an int* array[10]; and through a function I want to assign the array[0] to be the location of a particular number say, 5. What should the argument of the function look like. I have tried:
void insert(int* array);
but it didn't work.
Arrays are always passed as a pointer pointing to the beginning of the array, even if you don't write it explicitly. So given this declaration of an array from your question:
int *array[10];
Both the following functions will accept a pointer to such an array:
int foo(int *array[]);
int foo(int **array);
They are just equivalent and I would suggest you use the second form, because it makes it explicit what type really is passed to the function.
inside the function, you can access any element, because the indexers are define the same way on a pointer to an array as on the array itself:
int foo(int **array)
{
int *sixthElement = array[5];
// [...]
}
Additional stylistic note: In C, it's common practice to attach the * when declaring a pointer to the identifier, not to the type, ie better write
int *array[10];
instead of
int* array[10];
This is because in a C declaration, there's no such thing as a pointer type, there's a pointer declarator (consisting of the *, optional qualifiers and the identifier) and this declarator declares a variable to be a pointer to the specified type. It's a subtle difference, but if you ever try to declare more than one variable in one line (don't do this, it's just for explanation here), you will notice it:
int *a, b; // <- declares a as a pointer to int, b just as an int
When declaring a functions which takes function pointer as argument as mentioned below the compiler throws error.
void func_dec(int x, void(*)() funcptr);
Whereas it accepts below declaration,
void func_dec(int x, void(*funcptr)());
Why the compiler could not recognize the former declaration though it looks logical.
It is illegal because the formal definition in the language standard says so. As for the reason why it is that way, and it really may seem obscure, here it is:
From The New C Standard: An Economic and Cultural Commentary (v 1.2 from June 24, 2009, section 6.7 Declarations):
The intent of this syntax is for an identifier’s declarator to have
the same visual appearance as an instance of that identifier in an
expression. For instance, in:
int x[3], *y, z(void);
char (*f(int))[];
the identifier x might appear in the source as an indexed
array, y as a dereferenced pointer, and z as a function call. An
example of an expression using the result of a call to f is
(*f(42))[1].
And the same from The Development of the C Language by Dennis M. Ritchie:
Thus,
int i, *pi, **ppi;
declare an integer, a pointer to an integer, a
pointer to a pointer to an integer. The syntax of these declarations
reflects the observation that i, *pi, and **ppi all yield an int type
when used in an expression. Similarly,
int f(), *f(), (*f)();
declare
a function returning an integer, a function returning a pointer to an
integer, a pointer to a function returning an integer;
int *api[10], (*pai)[10];
declare an array of pointers to integers, and a pointer to
an array of integers. In all these cases the declaration of a variable
resembles its usage in an expression whose type is the one named at
the head of the declaration.
This is because,
void(*)() funcptr
is in invalid syntax on it's own.
Just supply the type while writing the function declaration,
void func_dec(int , void(*) ());
it should be enough. Otherwise, if you want to specify the variable name also, write
void func_dec(int x, void(*funcptr) ());
The function parameter name should go in the same place as the function name goes when you declare a function.
Function declaration:
void func(); // correct syntax
void() func; // incorrrect syntax
Function pointer declaration:
void (*func_ptr)(); // correct syntax
void (*)() func_ptr; // incorrect syntax
Declaring a function pointer becomes easier if you use the following trick:
Take the function declaration. Replace the function name with (*pointerName), or (*) if you want an unnamed version.
Example:
int func1(char* parm1); // function
int (*func1_ptr)(char* parm1); // function pointer
// function taking a function pointer as parameter:
void foo(int (*func1_ptr)(char*));
// The same declaration with an unnamed parameter:
void foo(int (*)(char*));
int (*(*q)(int (*)()))();
Ok, I start with: q is a pointer to a function, which takes... Not sure what should follow next, but perhaps it's ...a pointer to function, which takes nothing and returns int, and returns pointer to a function, which takes nothing and returns int.
The trick is that q itself is a function pointer that returns and takes a function pointer. cdecl says:
declare q as pointer to function (pointer to function returning int) returning pointer to function returning int
Find the lefmost identifier, then work your way out remembering that *a[] is an array of pointer, (*a)[] is a pointer to an array, *f() is a function returning a pointer, and (*f)() is a pointer to a function. Remember that in a prototype you only need to provide the type of the parameter; int f( int ); declares f as a function that takes a single int parameter; int f( int * ); declares f as a function that takes a single int pointer as a parameter. Similarly, int f( int (*)[N] ); declares f as a function that takes a pointer to an array as a parameter. Apply these rules recursively to any parameters in the function.
Thus:
q -- q
*q -- is a pointer to
(*q)( ) -- a function
(*q)( * ) -- that takes a pointer to
(*q)( (*)()) -- a function
(*q)(int (*)()) -- returning int
*(*q)(int (*)()) -- returning a pointer to
(*(*q)(int (*)()))() -- a function
int (*(*q)(int (*)()))(); -- returning int
You are right.
q is a pointer point to a function passing an pointer to a function (passing nothing returning int) returning a pointer to a function (passing nothing returning int).
See here.
http://c-faq.com/decl/spiral.anderson.html
According to Precedence and associativity of Operators in the C Programming language.
You can understand it in the following steps:
int (*(*q)(int (*)()))();
q->*->(int (*)())->*->()->int
1 2 3 4 5
1:q is a pointer
2:q is a function pointer, the function it points to has a parameter int (*)(), which is also a function pointer, points to a function has no parameters and return type is int.
3:q is a function pointer, the function it pointers to has parameter int (*)(), which is also a function pointer, points to a function has no parameters and return type is int. And
the function which q points to has a return type : pointer.
4:q is a function pointer, the function it pointers to has parameter int (*)(), which is also a function pointer, points to a function has no parameters and return type is int. And
the function which q points to has a return type : pointer(this pointer also points to a function which has no parameter).
5:q is a function pointer, the function it pointers to has parameter int (*)(), which is also a function pointer, points to a function has no parameters and return type is int. And
the function which q points to has a return type : pointer(this pointer also points to a function which has no parameter and the function's return type is int).
Im trying to figure out what the function declarations mean:
int *f();
and
int (*g)();
int *f();
The above line is the declaration of a function f that has an unspecified number of parameters and that returns an int *.
int (*g)();
The above line is the declaration of a pointer g to a function that has an unspecified number of parameters and that returns an int.
As an addition to the other correct answers here, I thought I'd mention that cdecl(1) is a handy tool for deciphering these sorts of declarations:
$ cdecl
Type `help' or `?' for help
cdecl> explain int *f();
declare f as function returning pointer to int
cdecl> explain int (*g)();
declare g as pointer to function returning int
cdecl may already be installed on your machine, or you can use it via a handy web interface at http://cdecl.org.
f is a function, returning int* and g is a pointer to function returning int.
Postfix operators such as function-call () have higher precedence than unary operators like *, so
T *f();
reads as
f -- f
f() -- is a function (() binds before *)
*f() -- returning a pointer
T *f(); -- to T (for some type T)
If you want to force * to bind before (), you must explicitly group with parentheses, so
T (*g)();
reads as
g -- g
(*g) -- is a pointer
(*g)() -- to a function
T (*g)(); -- returning T.
The rule is similar for arrays: T *a[N] is an array of pointer to T, whereas T (*p)[N] is a pointer to an array of T.
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]()
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.
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.
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[])()
.
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.