Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > I don't understand typedef example

Reply
Thread Tools

I don't understand typedef example

 
 
André Hänsel
Guest
Posts: n/a
 
      03-18-2009
Hi list,

"The C book", Chapter 8.3 states:

-----
As a word of warning, typedef can only be used to declare the type of
return value from a function, not the overall type of the function.
The overall type includes information about the function's parameters
as well as the type of its return value.

/*
* Using typedef, declare 'func' to have type
* 'function taking two int arguments, returning int'
*/
typedef int func(int, int);

/* ERROR */
func func_name{ /*....*/ }

/* Correct. Returns pointer to a type 'func' */
func *func_name(){ /*....*/ }
-----

This does not make any sense to me. He says that it is not possible to
typedef the function parameters' types and in the next line (the
comment) he says that he declares "func" to be "function taking two
int arguments" using typedef.

Can you explain this to me?

Regards,
André
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      03-18-2009
André Hänsel <(E-Mail Removed)> writes:
> Hi list,
>
> "The C book", Chapter 8.3 states:
>
> -----
> As a word of warning, typedef can only be used to declare the type of
> return value from a function, not the overall type of the function.
> The overall type includes information about the function's parameters
> as well as the type of its return value.
>
> /*
> * Using typedef, declare 'func' to have type
> * 'function taking two int arguments, returning int'
> */
> typedef int func(int, int);
>
> /* ERROR */
> func func_name{ /*....*/ }
>
> /* Correct. Returns pointer to a type 'func' */
> func *func_name(){ /*....*/ }
> -----
>
> This does not make any sense to me. He says that it is not possible to
> typedef the function parameters' types and in the next line (the
> comment) he says that he declares "func" to be "function taking two
> int arguments" using typedef.


You can declare a typedef for a function type, but you can't use such
a typedef to define a function of that type.

But given that func is a typedef for a function type, func* is a
pointer-to-function type. In his "Correct." example, he doesn't
declare func_name as a function of type func; he declares it as a
function that returns a func*.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail 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"
 
Reply With Quote
 
 
 
 
Fred
Guest
Posts: n/a
 
      03-18-2009
On Mar 17, 8:56*pm, André Hänsel <(E-Mail Removed)> wrote:
> Hi list,
>
> "The C book", Chapter 8.3 states:
>
> -----
> As a word of warning, typedef can only be used to declare the type of
> return value from a function, not the overall type of the function.
> The overall type includes information about the function's parameters
> as well as the type of its return value.
>
> /*
> * Using typedef, declare 'func' to have type
> * 'function taking two int arguments, returning int'
> */
> typedef int func(int, int);
>
> /* ERROR */
> func func_name{ /*....*/ }
>
> /* Correct. Returns pointer to a type 'func' */
> func *func_name(){ /*....*/ }
> -----
>
> This does not make any sense to me. He says that it is not possible to
> typedef the function parameters' types and in the next line (the
> comment) he says that he declares "func" to be "function taking two
> int arguments" using typedef.
>
> Can you explain this to me?
>


Consider this:
typedef char * String;

Then:

String myfunc(...);

So myfunc is a function that returns a string (i.e., a char *).

So your func is typedef'd to be a function taking two int
arguments and returning an int.

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.

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 ) {
/* somewhere this probably has something like this
* to invoke the function passed in:
*/
int n =(*proc)( a, b );

return n;
}

Then you can call mynewfunc:

int d = mynewfunc( 2, 5, func_name );

--
Fred K
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      03-18-2009
André Hänsel wrote:
> "The C book", Chapter 8.3 states:
>
> -----
> As a word of warning, typedef can only be used to declare the type of
> return value from a function, not the overall type of the function.
> The overall type includes information about the function's parameters
> as well as the type of its return value.
>
> /*
> * Using typedef, declare 'func' to have type
> * 'function taking two int arguments, returning int'
> */
> typedef int func(int, int);
>
> /* ERROR */
> func func_name{ /*....*/ }
>
> /* Correct. Returns pointer to a type 'func' */
> func *func_name(){ /*....*/ }
> -----
>
> This does not make any sense to me. He says that it is not possible to
> typedef the function parameters' types and in the next line (the
> comment) he says that he declares "func" to be "function taking two
> int arguments" using typedef.
>
> Can you explain this to me?



"func" means a function taking two ints and returning an int. If you write:

func *func_name() { /*....*/ }

what you have is a function taking no arguments and returning a
pointer-to-func.

This:

func func_name { /*....*/ }

is not valid, period, because (a) func_name doesn't have an argument
list, and (b) func_name can't return a function, only a pointer-to-function.

It never occurred to me to try to use a function typedef to declare the
return value and arguments to another function; that's just not the way
the C syntax works. You could hack up something similar using #define
if you really wanted to, but why?

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Isaac Jaffe
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-18-2009
Fred <(E-Mail Removed)> writes:
> On Mar 17, 8:56*pm, André Hänsel <(E-Mail Removed)> wrote:
>> "The C book", Chapter 8.3 states:
>>
>> -----
>> As a word of warning, typedef can only be used to declare the type of
>> return value from a function, not the overall type of the function.
>> The overall type includes information about the function's parameters
>> as well as the type of its return value.
>>
>> /*
>> * Using typedef, declare 'func' to have type
>> * 'function taking two int arguments, returning int'
>> */
>> typedef int func(int, int);
>>
>> /* ERROR */
>> func func_name{ /*....*/ }
>>
>> /* Correct. Returns pointer to a type 'func' */
>> func *func_name(){ /*....*/ }
>> -----
>>
>> This does not make any sense to me. He says that it is not possible to
>> typedef the function parameters' types and in the next line (the
>> comment) he says that he declares "func" to be "function taking two
>> int arguments" using typedef.
>>
>> Can you explain this to me?
>>

>
> Consider this:
> typedef char * String;
>
> Then:
>
> 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 );
>
> return n;
> }
>
> 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 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"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-18-2009
Stephen Sprunk <(E-Mail Removed)> writes:

> André Hänsel wrote:

<snip>
>> typedef int func(int, int);
>>
>> /* ERROR */
>> func func_name{ /*....*/ }
>>
>> /* Correct. Returns pointer to a type 'func' */
>> func *func_name(){ /*....*/ }

<snip>
> This:
>
> func func_name { /*....*/ }
>
> is not valid, period, because (a) func_name doesn't have an argument
> list, and (b) func_name can't return a function, only a
> pointer-to-function.


It is often more trouble than it is worth to say why something is
invalid (since it is wrong, it could mean anything at all) but I think
you go to far with (b). If I had just read about C's type system and
knew nothing else, I would take

func func_name { /*....*/ }

to be a definition of func_name as a function that returns an int.
After all,

func func_name;

declares it as such, so why would C not permit a definition by adding
a block? Yes, your (a) is the key problem -- there is no obvious
argument list, but the implied type is fine.

--
Ben.
 
Reply With Quote
 
Fred
Guest
Posts: n/a
 
      03-18-2009
On Mar 18, 9:48*am, Keith Thompson <(E-Mail Removed)> wrote:
> Fred <(E-Mail Removed)> writes:
> > On Mar 17, 8:56*pm, André Hänsel <(E-Mail Removed)> wrote:
> >> "The C book", Chapter 8.3 states:

>
> >> -----
> >> As a word of warning, typedef can only be used to declare the type of
> >> return value from a function, not the overall type of the function.
> >> The overall type includes information about the function's parameters
> >> as well as the type of its return value.

>
> >> /*
> >> * Using typedef, declare 'func' to have type
> >> * 'function taking two int arguments, returning int'
> >> */
> >> typedef int func(int, int);

>
> >> /* ERROR */
> >> func func_name{ /*....*/ }

>
> >> /* Correct. Returns pointer to a type 'func' */
> >> func *func_name(){ /*....*/ }
> >> -----

>
> >> This does not make any sense to me. He says that it is not possible to
> >> typedef the function parameters' types and in the next line (the
> >> comment) he says that he declares "func" to be "function taking two
> >> int arguments" using typedef.

>
> >> Can you explain this to me?

>
> > Consider this:
> > typedef char * String;

>
> > Then:

>
> > 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 );

>
> > * *return n;
> > }

>
> > 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 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 -


Oops - I misread the original typedef - thought it was
typdef int (*func)(int, int);

--
Fred K
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      03-19-2009
On Mar 19, 7:03*am, Ben Bacarisse <(E-Mail Removed)> wrote:
> <snip>
> >> typedef int func(int, int);

>
> It is often more trouble than it is worth to say why something is
> invalid (since it is wrong, it could mean anything at all) but I think
> you go to far with (b). *If I had just read about C's type system and
> knew nothing else, I would take
>
> *func func_name { /*....*/ }
>
> to be a definition of func_name as a function that returns an int.


What are the names of the parameters? It
would be annoying as a programmer to have
to refer back to the definition of 'func',
to find out how to use a parameter, not to
mention maintenance problems if someone
mucks with the typedef.

I agree that it would be useful to have
some sort of syntax for defining a function
to match an existing typedef, but I can't
really think of any such good syntax to do this.
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      03-19-2009
On Mar 18, 4:56*pm, André Hänsel <(E-Mail Removed)> wrote:
> Hi list,
>
> "The C book", Chapter 8.3 states:
>
> -----
> As a word of warning, typedef can only be used to declare the type of
> return value from a function, not the overall type of the function.
> The overall type includes information about the function's parameters
> as well as the type of its return value.


This paragraph is completely wrong. A
function typedef can include the function's
formal parameter list. In fact the example
you give does exactly that. The following
code is wrong:

typedef int func(int, int);

func f;

int f(void) { return 0; }

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-19-2009
Old Wolf <(E-Mail Removed)> writes:

> On Mar 19, 7:03Â*am, Ben Bacarisse <(E-Mail Removed)> wrote:
>> <snip>
>> >> typedef int func(int, int);

>>
>> It is often more trouble than it is worth to say why something is
>> invalid (since it is wrong, it could mean anything at all) but I think
>> you go to far with (b). Â*If I had just read about C's type system and
>> knew nothing else, I would take
>>
>> Â*func func_name { /*....*/ }
>>
>> to be a definition of func_name as a function that returns an int.

>
> What are the names of the parameters?


Yes, that is the main problem. I agreed with that part of the post.

> It
> would be annoying as a programmer to have
> to refer back to the definition of 'func',
> to find out how to use a parameter, not to
> mention maintenance problems if someone
> mucks with the typedef.


Yes. The typedef may have no named parameters, or there may be more
than one typedef with different names (depending on #if for example)
so it would be a nightmare.

> I agree that it would be useful to have
> some sort of syntax for defining a function
> to match an existing typedef, but I can't
> really think of any such good syntax to do this.


One could do:

typedef int functype(int, int);

(functype f)(a, b)
{
return a + b;
}

You could be permitted to repeat the types if you like:

int (functype f)(int a, int b) { ... }

and the compiler would check that they match.

The parentheses group the function types with name and though odd, not
so very odd since C uses ()s for grouping in types already.

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
CRTP-problem: How can the base class typedef a derived class' typedef? oor C++ 0 05-20-2008 12:39 PM
Don't understand odd looking typedef Angus C++ 6 03-31-2008 10:34 PM
unable to understand this typedef Sanchit C Programming 1 03-20-2008 02:38 PM
Help to understand 'array of classes' example ohaya Java 4 10-17-2005 09:13 PM
Read all of this to understand how it works. then check around on otherRead all of this to understand how it works. then check around on other thelisa martin Computer Support 2 08-18-2005 06:40 AM



Advertisments