Consider this:
typedef char * String;
String myfunc(...);
So myfunc is a function that returns a string (i.e., a char *).
That particular typedef is a bad idea, just because of the name.
A char* is not a string. A char* value can point to (the first
character of) a string. A "string" is defined as "a contiguous
sequence of characters terminated by and including the first null
character"; it is *not* a pointer. Suggested reading: sections 6
and 8 of the comp.lang.c FAQ, <
http://www.c-faq.com>.
But apart from the terminology, yes, myfunc returns a char*.
So your func is typedef'd to be a function taking two int
arguments and returning an int.
Right.
Functions, like objects, have types. If I define a function:
int foo(int n) { return n; }
then the function foo has a type that can be described as "function
taking an int argument and returning an int result". This type
can be written in C as "int (int)" (the type name is obtained by
taking the declaration and dropping the function's name). It's
important to keep in mind that a function and a function type
are two different things, just as an object (variable) and its
type are two different things.
The purpose of a typedef is to create a new name, an alias, for an
existing type. You can do this for a function type as easily as for
any other type. (Well, almost as easily; the syntax can be a bit
daunting.)
So the declaration:
typedef int func(int, int);
declare "func" as a name (an alias) for the type "function taking
two int arguments returning an int result", or "int(int, int)".
Once you've declared this alias, you can use it almost anywhere you
can use the original type. For example:
func *ptr;
declared ptr as a pointer object that can points to a function of the
appropriate type, and
func *array_of_pointers[42];
declares array_of_pointers as an array of such pointers.
Then you declare
func func_name(...);
Your intent was probably to try to show that func_name is
a function taking two int arguments and returning an int.
But in reality you have said that func_name is a function
that returns a func - that is, a function that returns
a function that takes two int args and returns an int.
Which is illegal. You can't legally have a function that returns a
function. You *can* have a function that returns a function pointer.
One common use of such a typedef is when passing a
function as an argument. For example,
int func_name( int a, int b ) {...};
int mynewfunc( int x, int y, func proc ) {
Again, this is illegal, since you can't have a parameter of function
type. You can have a parameter of pointer-to-function type, so this
would be legal (and is probably what you meant):
int mynewfunc( int x, int y, func *proc ) {
/* somewhere this probably has something like this
* to invoke the function passed in:
*/
int n =(*proc)( a, b );
Then you can call mynewfunc:
int d = mynewfunc( 2, 5, func_name );
func_name is a function, so yes, given that mynewfunc takes an
argument of type func*, this call is valid. Any expression of
function type, including a function name, is implicitly converted to a
pointer to the function.
Given that func is a typedef for a function type, you declare
a function of that type:
func foo;
But you can't use it to *define* the same function:
func foo { return 42 }; /* ILLEGAL */
In my opinion, it's clearer *not* to use the typedef in the function
declaration. (It's perfectly ok to use a typedef as *part of* a
function declaration, such as "func *bar(void)".) I prefer to keep a
function's declaration and definition as similar as possible, so I'd
write:
/* declaration: */
int foo(int a, int b);
/* definition: */
int foo(int a, int b) { /* ... */ }
Finally, you can declare a typedef either for the function type itself
or for a pointer to the function type:
typedef int func(int, int);
typedef int *func_ptr(int, int);
There are arguments for both forms. In code that I've seen, the
latter form is more common than the former; I think a lot of C
programmers aren't even aware that you can declare a typedef for
a function type. On the other hand, declaring a typedef for a
pointer type is generally a bad idea; the fact that something is a
pointer is an important part of the information you need to use it,
and hiding that information behind an alias can cause confusion.
On the other other hand, this argument isn't as strong for
pointers to functions as it is for pointers to objects. You should
be familiar with both forms.
--
Keith Thompson (The_Other_Keith) (e-mail address removed) <
http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"- Hide quoted text -
- Show quoted text -