Confusion on typedef functions

A

arnuld

Here is the typdef from a the Free Library named scew:

typedef unsigned int SCEW_CALLBACK(scew_parser* parser);

what exactly is this. I understand "typedef unsigned int my_int" very
well. But what does SCEW_CALLBACK will represent ?

A functions that returns an unisgned int and takes a pointer to
scew_parser as arguments ?

If we want we could simply have used the declaration:

unisgned int MY_SCEW_CALLBAC( scew parser *);


The problem with the original SCEW_CALLBACK is that we can not use
this typedef to define some function but we can use pointer to that
type:
http://groups.google.com/group/comp...lnk=gst&q=typedef+a+function#27d255a4222f7d19

Hence I can call SCEW_CALLBACK() an incomplete typedef because even
after typedef we can not use it to define types (but only pointers).
But the basic question of my post is why do we need to typdef a
function when can not use it as a type. We can simply doa function
delcaration it in our header. Is there any replacement for this kind
of confusing typedefs ?
 
J

Jens Thoms Toerring

arnuld said:
Here is the typdef from a the Free Library named scew:
typedef unsigned int SCEW_CALLBACK(scew_parser* parser);
what exactly is this. I understand "typedef unsigned int my_int" very
well. But what does SCEW_CALLBACK will represent ?
A functions that returns an unisgned int and takes a pointer to
scew_parser as arguments ?

That's right. But it typedef's not a function type, it type-
def's a type of pointer, a pointer to a function.
If we want we could simply have used the declaration:
unisgned int MY_SCEW_CALLBAC( scew parser *);
The problem with the original SCEW_CALLBACK is that we can not use
this typedef to define some function but we can use pointer to that
type:
http://groups.google.com/group/comp...lnk=gst&q=typedef+a+function#27d255a4222f7d19

Yes, because the typedef is for a (function) pointer, not
for a function. It's the same as with e.g.

typedef char * string;

That typedefs 'string' to mean a pointer to char. You also
can't use the type 'string' to create a char - you can only
use it in the declaration or definition of pointers to char.
Same with typedefs for function pointers - you can now use
the name to create pointers of that type but not functions.
Hence I can call SCEW_CALLBACK() an incomplete typedef because even
after typedef we can not use it to define types (but only pointers).
But the basic question of my post is why do we need to typdef a
function when can not use it as a type. We can simply doa function
delcaration it in our header. Is there any replacement for this kind
of confusing typedefs ?

As already pointed out, you can't typedef a function, you
only can typedef a function pointer. And in certain circum-
stances a typedef for a function can help a lot to make
things easier to read. One example is the definition of the
(POSIX) signal() function. If you don't use a typedef then
its declaration looks like this

void ( * signal( int signum, void ( * handler )( int ) ) )( int );

Many people understandably have problems grasping what that
is supposed to mean. But if you slit it up using a typedef
and write instead

typedef void ( * sighandler_t )( int );
sighandler_t signal( int signum, sighandler_t handler );

it immediately becomes a lot easier to understand - signal()
is a function that returns a pointer to a function and takes
two arguments, an int and a pointer to a function (of type
'sighandler_t).

And in this example the function is still rather simple,
think what happens if there are several function pointer
involved (that in turn point to functions that themselves
expect or return function pointers etc.) - then you end up
with an unreadable (at least for humans) mess.

Another place where typedefs for function pointers come
handy is when you have e.g. structures that contain
function pointers, e.g. pointers to callback functions.
Wouldn't you prefer

typedef int ( * MOUSE_CB )( FL_OBJECT * obj, XEvent * xev, void * data );
typedef void ( * KBD_CB)( FL_OBJECT * obj, int keycode );

structure {
Window w;
Display d;
MOUSE_CB my_mouse_handler;
KBD_CB my_keyboard_handler;
} x;

to

structure {
Window w;
Display d;
int ( * my_mouse_handler )( FL_OBJECT *obj, XEvent * xev,
void * data );
void ( * my_keyboard_handler )( FL_OBJECT * obj, int keycode );
} x;

especially if this structure would be a lot longer?

Regards, Jens
 
B

Ben Bacarisse

That's right. But it typedef's not a function type, it type-
def's a type of pointer, a pointer to a function.

No, it just names a function type. Not a pointer type of any kind.
 
B

Ben Bacarisse

arnuld said:
Here is the typdef from a the Free Library named scew:

typedef unsigned int SCEW_CALLBACK(scew_parser* parser);

what exactly is this. I understand "typedef unsigned int my_int" very
well. But what does SCEW_CALLBACK will represent ?

A functions that returns an unisgned int and takes a pointer to
scew_parser as arguments ?

Exactly right.
If we want we could simply have used the declaration:

unisgned int MY_SCEW_CALLBAC( scew parser *);

True, but the purpose of the typedef is probably to simplify other
declarations and definitions. For example, an array of pointers to
call back function becomes:

SCEW_CALLBACK *cba[] = { /* ... */ };

which looks exactly like any other array of pointers. A function that
sets a call back pointer and returns the old function pointer looks
like this:

SCEW_CALLBACK *set_callback(OBJECT *where, SCEW_CALLBACK *new);

This declaration is truly horrid without any typedef to help out:

unsigned int (*set_callback(OBJECT *where,
unsigned int (*new)(sew_parser *)))(sew_parser *);

(and it is likely that I have got that wrong!).

Most people do this by defining a pointer-to-function type rather than
a function type, but you should learn to read both. I prefer this
method. For one thing, if you need to declare a lot of the functions
in order to set up some sort of table of them you can just do this:

SCEW_CALLBACK csew_print, scew_comment, scew_declare, scew_end;
SCEW_CALLBACK *actions[] = {
scew_print, scew_comment, scew_declare, scew_end
};

But the basic question of my post is why do we need to typdef a
function when can not use it as a type.

Ah, but you can. Pretty much the only thing you can't do is define a
function using it.
 

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

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top