typedef with function pointers

G

Googy

Hi!!
Can any one explain me the meaning of following notations clearly :

1. typedef char(*(*frpapfrc())[])();
frpapfrc f;

2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;

3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;

4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;

5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;

What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..
Thanks in advance...

Gaurav
 
C

CBFalconer

Googy said:
Can any one explain me the meaning of following notations clearly :

1. typedef char(*(*frpapfrc())[])();
frpapfrc f;

2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;

3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;

4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;

5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;

What are f,p,q,x,y?? and how?

They are objects of the type declared. For what that type is, see
the preceding typedef.
 
T

Tor Rustad

Googy said:
Hi!!
Can any one explain me the meaning of following notations clearly :

1. typedef char(*(*frpapfrc())[])();
frpapfrc f;

2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;

3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;

4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;

5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;

What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..

homework-o-meter = 100%

Hint: cdecl
 
V

vardhan

Googy said:
Hi!!
Can any one explain me the meaning of following notations clearly :
1. typedef char(*(*frpapfrc())[])();
frpapfrc f;
2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;
3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;
4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;
5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;
What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..

homework-o-meter = 100%

Hint: cdecl

Heres are quick question:

A typical typedef for a data type like a struct goes like:

typedef struct X { ...} XStruct;

where XStruct is now "struct X". Why don't we follow a similar way to
define function pointers? Or is it that the placement of the type
defined follows a similar rule for both these declarations?

-Vardhan
 
B

Ben Bacarisse

vardhan said:
Googy said:
Hi!!
Can any one explain me the meaning of following notations clearly :
1. typedef char(*(*frpapfrc())[])();
frpapfrc f;
2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;
3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;
4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;
5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;
What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..

homework-o-meter = 100%

Hint: cdecl

Heres are quick question:

A typical typedef for a data type like a struct goes like:

typedef struct X { ...} XStruct;

where XStruct is now "struct X". Why don't we follow a similar way to
define function pointers?

We can, but the pointers are the problem. For example:

typedef int XFunc(void);

defines XFunc to be a name for the type "function of no parameters
returning int". There is an exact equivalence between this and the
code you posted to typedef a "struct X".

If you want a typdef for a pointer to a "struct X" we just add a star,
because the syntax works:

typedef struct X { ... } *XStructPtr;

but you can't just add a star in front of XFunc above because in that
case the start will be associated with the return type of the
function:

typedef int *XFunc(void);

This is a synonym for "function of no parameters returning a pointer
to int". To alter this association, we need brackets:

typedef int (*XFuncPtr)(void);

Now XFuncPtr is "pointer to function of no parameters returning an
int". Of course. given the first simple typedef, we can use it to
define the second more easily:

typedef int XFunc(void);
typedef XFunc *XFuncPtr;

and many people prefer to do this for complex point to function (and
array) types.
Or is it that the placement of the type
defined follows a similar rule for both these declarations?

I could not understand that. I hope you did not mean what I just said
at great length!
 
M

Martin Wells

Googy:
Can any one explain me the meaning of following notations clearly :

1. typedef char(*(*frpapfrc())[])();
frpapfrc f;

2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;

3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;

4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;

5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;

What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..
Thanks in advance...


Given this looks like a homework question, I'll explain how it works
rather than giving you the answer.

First off, typedef has the same syntax as defining variables. For
instance:

int arr[5];

The above defines an array called "arr" with five int elements.

typedef int arr[5];

The above declares a type called "arr" which is an array of five int
elements.

If you're trying to break a complicated declaration down, then start
with the name. I'm not familiar with C99, so I'm going to change the
first declaration a little for it to be C89:

typedef char(*(*frpapfrc(void))[5])(void);

The stuff right beside the name tells you that firstly:
1: It's a function that takes no arguments
2: That returns a pointer

Now take that stuff out and you're left with:

typedef char(*frpapfrc[5])(void);

This tells us that:
3: It's an array of five elements
4: Each element is a pointer

Again, strip that stuff out:

typedef char frpapfrc (void);

5: This is a function with no parameters that returns a char.

Now just put them in order:

A function that takes no arguments, and returns a pointer to an array
of five pointers to functions which take no arguments and which return
a char.

You can test it out as follows:

typedef char(*(*frpapfrc(void))[5])(void);

typedef char A(void);

typedef A *B[5];

typedef B *C;

typedef C D(void);



int main(void)
{
D *p1 = 0;
frpapfrc *p2 = p1; /* Hopefully we don't get a type mis-match */

return 0;
}


Martin
 
E

Eric Sosman

vardhan said:
Googy said:
Hi!!
Can any one explain me the meaning of following notations clearly :
1. typedef char(*(*frpapfrc())[])();
frpapfrc f;
2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;
3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;
4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;
5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;
What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..
homework-o-meter = 100%

Hint: cdecl

Heres are quick question:

A typical typedef for a data type like a struct goes like:

typedef struct X { ...} XStruct;

where XStruct is now "struct X". Why don't we follow a similar way to
define function pointers? Or is it that the placement of the type
defined follows a similar rule for both these declarations?

Forget about the typedef for a moment, and recall C's
practice that "declaration mimics use." When you write
`int x;' you say "x is an int." When you write `int *x;'
you say "*x is an int, hence x is a pointer to int." When
you write `int x[42];' you say "x[index] is an int, hence
x is an array of int. The position of x with respect to
the other elements of the declaration depends on the way
x would be used in an expression: The type comes first,
followed by a sort of "expression template" involving the
identifier that's being declared.

When you write `int f(double x);' you say "f(42.0) is
an int, hence f is a function taking a double and returning
an int." When you write `int (*f)(double x);' you say
"(*f)(42.0) is an int, hence f is a pointer to a function
taking a double and returning an int." Again, the position
of f with respect to the other elements of the declaration
is the position f would have in an actual expression.

Now re-insert the typedef. Syntactically, this is just
like inserting static or extern or register or auto, and does
not affect what goes on in the rest of the declaration. The
others specify where the new identifier's object is to be
stored; typedef says "It's not really an object at all, but
an alias for the type that the object would have had if the
typedef keyword hadn't been there."

int x; /* x is an int; make one */
extern int x; /* x is an int residing elsewhere */
typedef int x; /* x is an alias for int */

int (*f)(double); /* f is a function ptr; make one */
extern int (*f)(double); /* f is a function ptr elsewhere */
typedef int (*f)(double); /* f is an alias for function ptr */
 
C

Charles Richmond

Googy said:
Hi!!
Can any one explain me the meaning of following notations clearly :

1. typedef char(*(*frpapfrc())[])();
frpapfrc f;

2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;

3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;

4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;

5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;

What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..
Thanks in advance...

Just use the precedence of *, (), and []. Start from
within the inner grouping parentheses pair and just
read the type. Use words like "pointer to", "function
returning", and "x element array of".

Take the first problem. The innermost grouping is
(*frpapfrc()). That reads as "function returning
pointer to"... remember that () has higher precedence
than *.

So far we have:

typedef char (*("function returning pointer to")[])();

Because [] has a higher precedence than *, we continue

typedef char ("function returning pointer to array of pointers")();

The final substitution gives:

"function returning pointer to array of pointers to functions returning
character"

You can use this technique to analyze the other declarations.
 
G

Googy

Googy:


Can any one explain me the meaning of following notations clearly :
1. typedef char(*(*frpapfrc())[])();
frpapfrc f;
2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;
3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;
4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;
5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;
What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..
Thanks in advance...

Given this looks like a homework question, I'll explain how it works
rather than giving you the answer.

First off, typedef has the same syntax as defining variables. For
instance:

int arr[5];

The above defines an array called "arr" with five int elements.

typedef int arr[5];

The above declares a type called "arr" which is an array of five int
elements.

If you're trying to break a complicated declaration down, then start
with the name. I'm not familiar with C99, so I'm going to change the
first declaration a little for it to be C89:

typedef char(*(*frpapfrc(void))[5])(void);

The stuff right beside the name tells you that firstly:
1: It's a function that takes no arguments
2: That returns a pointer

Now take that stuff out and you're left with:

typedef char(*frpapfrc[5])(void);

This tells us that:
3: It's an array of five elements
4: Each element is a pointer

Again, strip that stuff out:

typedef char frpapfrc (void);

5: This is a function with no parameters that returns a char.

Now just put them in order:

A function that takes no arguments, and returns a pointer to an array
of five pointers to functions which take no arguments and which return
a char.

You can test it out as follows:

typedef char(*(*frpapfrc(void))[5])(void);

typedef char A(void);

typedef A *B[5];

typedef B *C;

typedef C D(void);

int main(void)
{
D *p1 = 0;
frpapfrc *p2 = p1; /* Hopefully we don't get a type mis-match */

return 0;

}

Martin

Thanks Martin it was very explanatory and i was able to solve the
problems further, actually i was reading the topic of function
pointers and came across these difficulties...Thanks buddy!!
 
G

Googy

vardhan said:
Googy wrote:
Hi!!
Can any one explain me the meaning of following notations clearly :
1. typedef char(*(*frpapfrc())[])();
frpapfrc f;
2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;
3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;
4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;
5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;
What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..
homework-o-meter = 100%
Hint: cdecl
Heres are quick question:
A typical typedef for a data type like a struct goes like:
typedef struct X { ...} XStruct;
where XStruct is now "struct X". Why don't we follow a similar way to
define function pointers? Or is it that the placement of the type
defined follows a similar rule for both these declarations?

Forget about the typedef for a moment, and recall C's
practice that "declaration mimics use." When you write
`int x;' you say "x is an int." When you write `int *x;'
you say "*x is an int, hence x is a pointer to int." When
you write `int x[42];' you say "x[index] is an int, hence
x is an array of int. The position of x with respect to
the other elements of the declaration depends on the way
x would be used in an expression: The type comes first,
followed by a sort of "expression template" involving the
identifier that's being declared.

When you write `int f(double x);' you say "f(42.0) is
an int, hence f is a function taking a double and returning
an int." When you write `int (*f)(double x);' you say
"(*f)(42.0) is an int, hence f is a pointer to a function
taking a double and returning an int." Again, the position
of f with respect to the other elements of the declaration
is the position f would have in an actual expression.

Now re-insert the typedef. Syntactically, this is just
like inserting static or extern or register or auto, and does
not affect what goes on in the rest of the declaration. The
others specify where the new identifier's object is to be
stored; typedef says "It's not really an object at all, but
an alias for the type that the object would have had if the
typedef keyword hadn't been there."

int x; /* x is an int; make one */
extern int x; /* x is an int residing elsewhere */
typedef int x; /* x is an alias for int */

int (*f)(double); /* f is a function ptr; make one */
extern int (*f)(double); /* f is a function ptr elsewhere */
typedef int (*f)(double); /* f is an alias for function ptr */

Thanks Eric for your explanation it was a concept told in a new way
which helped me to solve the problems further, Thanks very much once
again!!
 
G

Googy

Googy said:
Hi!!
Can any one explain me the meaning of following notations clearly :
1. typedef char(*(*frpapfrc())[])();
frpapfrc f;
2. typedef int (*(arr2d_ptr)())[3][4];
arr2d_ptr p;
3. typedef int (*(*(*ptr2d_fptr)())[10])();
ptr2d_fptr q;
4. typedef char (*(*arr_fptr[3])())[10];
arr_fptr x;
5. typedef float *(*(*(*ptr_fptr)())[10])();
ptr_fptr y;
What are f,p,q,x,y?? and how?
Please don't just answer what they are explain then clearly..
Thanks in advance...

Just use the precedence of *, (), and []. Start from
within the inner grouping parentheses pair and just
read the type. Use words like "pointer to", "function
returning", and "x element array of".

Take the first problem. The innermost grouping is
(*frpapfrc()). That reads as "function returning
pointer to"... remember that () has higher precedence
than *.

So far we have:

typedef char (*("function returning pointer to")[])();

Because [] has a higher precedence than *, we continue

typedef char ("function returning pointer to array of pointers")();

The final substitution gives:

"function returning pointer to array of pointers to functions returning
character"

You can use this technique to analyze the other declarations.

Thanks! very much for your clear and careful explanation, i was able
to solve the problems using this technique, thanks once again!!
 
D

Default User

Googy said:
On Sep 30, 11:39 pm, Eric Sosman <[email protected]> wrote:

[large snip]
Thanks Eric for your explanation it was a concept told in a new way
which helped me to solve the problems further, Thanks very much once
again!!

Please trim your posts to leave just enough quoted material for
context. In particular, snip the signatures, the parts following "-- "
(I've left the example above). A good newsreader would do that for you.
Alas, you use Google Groups, so no help there.




Brian
 
V

vardhan

We can, but the pointers are the problem. For example:

typedef int XFunc(void);

defines XFunc to be a name for the type "function of no parameters
returning int". There is an exact equivalence between this and the
code you posted to typedef a "struct X".

I have not seen this kind of typedef for a function name before.
Thanks.
Is it possible to use it in the code (similar to how a function
pointer can be used by taking the address of a function)? Can I now
declare a "variable" of type XFunc and initialize it - how?

e.g.

int func1(int i);
typedef int XFunc(int);
typedef int (*XFuncPtr)(int);

XFunc myFunc = funcl; // correct??
XFuncPtr myFuncPtr = &func1;
If you want a typdef for a pointer to a "struct X" we just add a star,
because the syntax works:

typedef struct X { ... } *XStructPtr;

but you can't just add a star in front of XFunc above because in that
case the start will be associated with the return type of the
function:

typedef int *XFunc(void);

This is a synonym for "function of no parameters returning a pointer
to int". To alter this association, we need brackets:

typedef int (*XFuncPtr)(void);

Now XFuncPtr is "pointer to function of no parameters returning an
int". Of course. given the first simple typedef, we can use it to
define the second more easily:

typedef int XFunc(void);
typedef XFunc *XFuncPtr;

and many people prefer to do this for complex point to function (and
array) types.

Thanks for the explanation.
I could not understand that. I hope you did not mean what I just said
at great length!

In a way yes, but you answered my question!

-Vardhan
 
V

vardhan

vardhanwrote:
Heres are quick question:
A typical typedef for a data type like a struct goes like:
typedef struct X { ...} XStruct;
where XStruct is now "struct X". Why don't we follow a similar way to
define function pointers? Or is it that the placement of the type
defined follows a similar rule for both these declarations?

Forget about the typedef for a moment, and recall C's
practice that "declaration mimics use." When you write
`int x;' you say "x is an int." When you write `int *x;'
you say "*x is an int, hence x is a pointer to int." When
you write `int x[42];' you say "x[index] is an int, hence
x is an array of int. The position of x with respect to
the other elements of the declaration depends on the way
x would be used in an expression: The type comes first,
followed by a sort of "expression template" involving the
identifier that's being declared.

When you write `int f(double x);' you say "f(42.0) is
an int, hence f is a function taking a double and returning
an int." When you write `int (*f)(double x);' you say
"(*f)(42.0) is an int, hence f is a pointer to a function
taking a double and returning an int." Again, the position
of f with respect to the other elements of the declaration
is the position f would have in an actual expression.
A question: here, as f, by definition, is a variable of type pointer
to a function which takes double and returns an int, I assume that it
can be used as such (without a typedef) to hold the address of a
function of that type. So if I do not use a typedef, I can just use:

int (*f)(double);

to define a variable f which is of the type explained above.
If I were to initialize this I would something like:

int func1(double) { return 0;}

f = &func1;

My question is, can I initialize the variable f in the declaration
itself.

i.e. as for any normal variable I could do:

int x = 5;

how can I do this for a variable which is a 1. Function pointer 2.
Function.

1. Function pointer:

int (*f)(double y) = &func1; // this should be correct.
int (*f1)(double y) { return 0; } // Is this allowed?

2. Function:

int (f)(double) = func1; // is this allowed?
int (f)(double) { return 0;} // Im actually just defining a function,
but I can also think
// of it as a variable of type function
which is declared and
// initialized at the same time! Am I
correct?

Now re-insert the typedef. Syntactically, this is just
like inserting static or extern or register or auto, and does
not affect what goes on in the rest of the declaration. The
others specify where the new identifier's object is to be
stored; typedef says "It's not really an object at all, but
an alias for the type that the object would have had if the
typedef keyword hadn't been there."

int x; /* x is an int; make one */
extern int x; /* x is an int residing elsewhere */
typedef int x; /* x is an alias for int */

int (*f)(double); /* f is a function ptr; make one */
extern int (*f)(double); /* f is a function ptr elsewhere */
typedef int (*f)(double); /* f is an alias for function ptr */

I think my question about the equivalence of the typedefs for struct
and function pointers got answered. Thanks!

-Vardhan
 
E

Eric Sosman

vardhan wrote On 10/04/07 12:11,:
[...]
When you write `int f(double x);' you say "f(42.0) is
an int, hence f is a function taking a double and returning
an int." When you write `int (*f)(double x);' you say
"(*f)(42.0) is an int, hence f is a pointer to a function
taking a double and returning an int." Again, the position
of f with respect to the other elements of the declaration
is the position f would have in an actual expression.

A question: here, as f, by definition, is a variable of type pointer
to a function which takes double and returns an int, I assume that it
can be used as such (without a typedef) to hold the address of a
function of that type. So if I do not use a typedef, I can just use:

int (*f)(double);

to define a variable f which is of the type explained above.
If I were to initialize this I would something like:

int func1(double) { return 0;}

f = &func1;

My question is, can I initialize the variable f in the declaration
itself.

Yes.

int func1(double x) { return 0; }

int (*f)(double) = func1;

Or another example, this time with just a function
declaration instead of a full-dress definition:

#include <math.h> /* declares atan2() and pow() */

double (*f2)(double, double) = atan2;
if (trig_confuses_me)
f2 = pow;
 
B

Ben Bacarisse

vardhan said:
I have not seen this kind of typedef for a function name before.
Thanks.
Is it possible to use it in the code (similar to how a function
pointer can be used by taking the address of a function)? Can I now
declare a "variable" of type XFunc and initialize it - how?

You can't. This is because variables can have function type. They
can, at best, be pointers to functions:

XFunc *fp = some_function_name;

You can use this sort of typedef to declare (but not define) a
function. For example, if you have code that has some operation type
defined as, say, a function taking two ints and returning an int you
can write this sort of code:

typedef int Operation(int, int);

extern Operation op_add, op_sub, op_mul, op_div;

struct expression {
struct expression *e1, *e2;
Operation *op;
};

...
struct expression *ep = malloc(sizeof *ep);
if (ep) {
ep->op = op_mul;
...
}
 
M

Mark McIntyre

You can't. This is because variables can have function type.

You mean "can't" in the above.
They can, at best, be pointers to functions:
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
D

David Thompson

Googy:
1. typedef char( *(*frpapfrc())[])();
If you're trying to break a complicated declaration down, then start
with the name. I'm not familiar with C99, so I'm going to change the
first declaration a little for it to be C89:

typedef char(*(*frpapfrc(void))[5])(void);
Empty/omitted array bounds in places where they aren't needed (to
determine allocation, stride, or struct layout) are C89 and even K&R1.
What was added in C99 was 'variable length array' (VLA) and the
related variably-modified types; this example wasn't that. Although
without the stride it might just as well and slightly easier return
pointer to (first of array which is) pointer to function etc.
The stuff right beside the name tells you that firstly:
1: It's a function that takes no arguments
2: That returns a pointer
Only after your change; empty parens as the OP had means unspecified
arguments (but fixed and unchanged by default argument promotions).
Now take that stuff out and you're left with:

typedef char(*frpapfrc[5])(void);
You might want to change the name to reflect the change: apfrc.
This tells us that:
3: It's an array of five elements
4: Each element is a pointer

Again, strip that stuff out:

typedef char frpapfrc (void);

5: This is a function with no parameters that returns a char.
As above: was unspecified params; name 'frc'.
Now just put them in order:

A function that takes no arguments, and returns a pointer to an array
of five pointers to functions which take no arguments and which return
a char.
- formerly david.thompson1 || achar(64) || worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,538
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top