I don't understand typedef example

Discussion in 'C Programming' started by André Hänsel, Mar 18, 2009.

  1. 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é
     
    André Hänsel, Mar 18, 2009
    #1
    1. Advertising

  2. André Hänsel <> 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.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 18, 2009
    #2
    1. Advertising

  3. André Hänsel

    Fred Guest

    On Mar 17, 8:56 pm, André Hänsel <> 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
     
    Fred, Mar 18, 2009
    #3
  4. 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
     
    Stephen Sprunk, Mar 18, 2009
    #4
  5. Fred <> writes:
    > On Mar 17, 8:56 pm, 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?
    >>

    >
    > 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) <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"
     
    Keith Thompson, Mar 18, 2009
    #5
  6. Stephen Sprunk <> 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.
     
    Ben Bacarisse, Mar 18, 2009
    #6
  7. André Hänsel

    Fred Guest

    On Mar 18, 9:48 am, Keith Thompson <> wrote:
    > Fred <> writes:
    > > On Mar 17, 8:56 pm, 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?

    >
    > > 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)  <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
     
    Fred, Mar 18, 2009
    #7
  8. André Hänsel

    Old Wolf Guest

    On Mar 19, 7:03 am, Ben Bacarisse <> 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.
     
    Old Wolf, Mar 19, 2009
    #8
  9. André Hänsel

    Old Wolf Guest

    On Mar 18, 4:56 pm, André Hänsel <> 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; }
     
    Old Wolf, Mar 19, 2009
    #9
  10. Old Wolf <> writes:

    > On Mar 19, 7:03 am, Ben Bacarisse <> 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.
     
    Ben Bacarisse, Mar 19, 2009
    #10
  11. Thanks for all your answers. They make it clear. So I understand that
    all the author wanted to say is that there is no syntax in C to use a
    typedef'd function type to define (or even declare) a function of that
    type.

    Since the only use of such a typedef is to make a type "pointer to
    such a function" I probably will stick to the "typedef int
    *pointer_to_such_function(int,int)" syntax in my own code.
     
    André Hänsel, Mar 22, 2009
    #11
  12. On 23 Mrz., 01:17, pete <> wrote:
    > André Hänsel wrote:
    > > Thanks for all your answers. They make it clear. So I understand that
    > > all the author wanted to say is that there is no syntax in C to use a
    > > typedef'd function type to define (or even declare) a function of that
    > > type.

    >
    > > Since the only use of such a typedef is to make a type "pointer to
    > > such a function" I probably will stick to the "typedef int
    > > *pointer_to_such_function(int,int)" syntax in my own code.

    >
    > Did you understand the part of the answers
    > which explained about the author being wrong?
    >
    > You *can* use a typedef to declare a function.


    Actually I don't think the author is wrong but he expresses the facts
    in a very unfortunate way. I think by the sentence "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." he means
    something like "The typedef'd 'type name' cannot be used to define a
    function of this type, it can only be used to define a function
    returning a pointer to a funtion of this type."
    This is what you meant by "using a typedef to declare a function",
    isn't it? Or is there really a way to define a function of this very
    type?
     
    André Hänsel, Mar 23, 2009
    #12
  13. On Sun, 22 Mar 2009 16:48:05 -0700 (PDT), André Hänsel
    <> wrote:

    >Thanks for all your answers. They make it clear. So I understand that
    >all the author wanted to say is that there is no syntax in C to use a
    >typedef'd function type to define (or even declare) a function of that
    >type.
    >
    >Since the only use of such a typedef is to make a type "pointer to
    >such a function" I probably will stick to the "typedef int
    >*pointer_to_such_function(int,int)" syntax in my own code.


    You probably meant
    typedef int (*ptr)(int, int);
    otherwise the asterisk binds to the int.

    --
    Remove del for email
     
    Barry Schwarz, Mar 23, 2009
    #13
  14. On Mar 18, 10:52 pm, Ben Bacarisse <> wrote:
    > Old Wolf <> writes:
    > > On Mar 19, 7:03 am, Ben Bacarisse <> 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.


    I saw that and got so excited that I copied it straight into an editor
    and tried to compile. It doesn't work. But I came up with a use that
    does work, declaring a function with a function-pointer arg which is
    declared by example.

    int b(int a, int b) {
    return a - b;
    }

    typedef typeof(b) functype;

    int gen_interface(int foo, functype *fp);

    --
    lxt
     
    luser-ex-troll, Mar 23, 2009
    #14
  15. André Hänsel <> writes:
    > On 23 Mrz., 01:17, pete <> wrote:
    >> André Hänsel wrote:
    >> > Thanks for all your answers. They make it clear. So I understand that
    >> > all the author wanted to say is that there is no syntax in C to use a
    >> > typedef'd function type to define (or even declare) a function of that
    >> > type.

    >>
    >> > Since the only use of such a typedef is to make a type "pointer to
    >> > such a function" I probably will stick to the "typedef int
    >> > *pointer_to_such_function(int,int)" syntax in my own code.

    >>
    >> Did you understand the part of the answers
    >> which explained about the author being wrong?
    >>
    >> You *can* use a typedef to declare a function.

    >
    > Actually I don't think the author is wrong but he expresses the facts
    > in a very unfortunate way. I think by the sentence "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." he means
    > something like "The typedef'd 'type name' cannot be used to define a
    > function of this type, it can only be used to define a function
    > returning a pointer to a funtion of this type."
    > This is what you meant by "using a typedef to declare a function",
    > isn't it? Or is there really a way to define a function of this very
    > type?


    The terms "declare" and "define" are not interchangeable. You can use
    a typedef to *declare* a function, where the typedef specifies the
    type of the function itself. You cannot similarly use a typedef to
    *define* a function. (Of course a typedef can be used in the
    function's return type or parameter types; it just can't be used for
    the type of the function itself.)

    For example, this is legal:

    #include <stdio.h>

    /* func_type is a function type, not a pointer-to-function type */
    typedef void func_type(void);

    /* A function declaration, not a definition: */
    func_type say_hello;

    int main(void) {
    say_hello();
    return 0;
    }

    /* A function definition: */
    void say_hello(void) {
    puts("Hello");
    }

    The function say_hello is of type func_type, but you cannot legally
    rewrite the *definition* of say_hello using the type name "func_type".

    And as a matter of style, I prefer not to use typedefs for function
    declarations either, since I like to keep declarations and definitions
    as similar as possible (apart from the lack of a body on the
    declaration, of course).

    (In the above, I largely ignored the fact that a definition is also a
    declaration.)

    --
    Keith Thompson (The_Other_Keith) <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"
     
    Keith Thompson, Mar 23, 2009
    #15
  16. luser-ex-troll <> writes:
    [snip]
    > I saw that and got so excited that I copied it straight into an editor
    > and tried to compile. It doesn't work. But I came up with a use that
    > does work, declaring a function with a function-pointer arg which is
    > declared by example.
    >
    > int b(int a, int b) {
    > return a - b;
    > }
    >
    > typedef typeof(b) functype;
    >
    > int gen_interface(int foo, functype *fp);


    typeof is non-standard; I think it's a gcc extension.

    --
    Keith Thompson (The_Other_Keith) <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"
     
    Keith Thompson, Mar 23, 2009
    #16
  17. luser-ex-troll <> writes:

    > On Mar 18, 10:52 pm, Ben Bacarisse <> wrote:

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

    >
    > I saw that and got so excited that I copied it straight into an editor
    > and tried to compile. It doesn't work.


    Yes, I hope it is clear I was talking about what one might do in a
    hypothetical language like C...

    > But I came up with a use that
    > does work, declaring a function with a function-pointer arg which is
    > declared by example.
    >
    > int b(int a, int b) {
    > return a - b;
    > }
    >
    > typedef typeof(b) functype;
    >
    > int gen_interface(int foo, functype *fp);


    typeof is (as has been pointed out already) non-standard but if you
    think about it, all C typedefs are declared "by example" -- you write
    an example declaration:

    int b(int a, int b);

    and simply replace the name with the name you want for the alias abd
    put typedef in front:

    typdef int functype(int a, int b);

    and now functype works like your typeof example. This is true of all
    tyepdefs -- they are example declarations with an extra keyword in
    front.

    --
    Ben.
     
    Ben Bacarisse, Mar 23, 2009
    #17
  18. On 23 Mrz., 03:37, pete <> wrote:
    > André Hänsel wrote:
    > > On 23 Mrz., 01:17, pete <> wrote:
    > >> André Hänsel wrote:
    > >>> Thanks for all your answers. They make it clear. So I understand that
    > >>> all the author wanted to say is that there is no syntax in C to use a
    > >>> typedef'd function type to define (or even declare) a function of that
    > >>> type.
    > >>> Since the only use of such a typedef is to make a type "pointer to
    > >>> such a function" I probably will stick to the "typedef int
    > >>> *pointer_to_such_function(int,int)" syntax in my own code.
    > >> Did you understand the part of the answers
    > >> which explained about the author being wrong?

    >
    > >> You *can* use a typedef to declare a function.

    >
    > > Actually I don't think the author is wrong but he expresses the facts
    > > in a very unfortunate way. I think by the sentence "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." he means
    > > something like "The typedef'd 'type name' cannot be used to define a
    > > function of this type, it can only be used to define a function
    > > returning a pointer to a funtion of this type."
    > > This is what you meant by "using a typedef to declare a function",
    > > isn't it?

    >
    > No.
    >
    > > Or is there really a way to define a function of this very type?

    >
    > No.
    > A typedef can be used to declare a function type.
    > A typedef can't be used to define a function.
    > I just posted this code recently:
    >
    > /* BEGIN new.c */
    >
    > #include <stdio.h>
    >
    > #define STRING1 "\n/* BEGIN output new.c */\n"
    > #define STRING2 "/* END output new.c */"
    >
    > typedef void *copyfunc(void *s1, const void *s2, size_t n);
    > /*
    > ** mem_cpy and mem_move
    > ** are functions declared with a copyfunc typedef.
    > */
    > copyfunc mem_cpy;
    > copyfunc mem_move;
    >
    > int main(void)
    > {
    >      char string1[sizeof STRING1];
    >      char string2[sizeof STRING2];
    >
    >      mem_cpy(string1, STRING1, sizeof string1);
    >      mem_move(string2, STRING2, sizeof string2);
    >      puts(string1);
    >      puts(string2);
    >      return 0;
    >
    > }
    >
    > void *mem_cpy(void *s1, const void *s2, size_t n)
    > {
    >            unsigned char *p1 = s1;
    >      const unsigned char *p2 = s2;
    >
    >      while (n-- != 0) {
    >          *p1++ = *p2++;
    >      }
    >      return s1;
    >
    > }
    >
    > void *mem_move(void *s1, const void *s2, size_t n)
    > {
    >            unsigned char *p1 = s1;
    >      const unsigned char *p2 = s2;
    >
    >      p2 += n;
    >      while (p2 != s2 && --p2 != s1) {
    >          ;
    >      }
    >      if (p2 != s2) {
    >          p2  = s2;
    >          while (n-- != 0) {
    >              p1[n] = p2[n];
    >          }
    >      } else {
    >          while (n-- != 0) {
    >              *p1++ = *p2++;
    >          }
    >      }
    >      return s1;
    >
    > }
    >
    > /* END new.c */
    >
    > --
    > pete


    Oh, now I understand. Of course I was aware of the difference between
    the declaration and the definition, I simply could not understand why
    a language may provide a syntax to declare a function using the
    typedef but *not* provide a syntax to *define* the function using it.
     
    André Hänsel, Mar 24, 2009
    #18
  19. On 23 Mrz., 03:01, Barry Schwarz <> wrote:
    > On Sun, 22 Mar 2009 16:48:05 -0700 (PDT), André Hänsel
    >
    > <> wrote:
    > >Thanks for all your answers. They make it clear. So I understand that
    > >all the author wanted to say is that there is no syntax in C to use a
    > >typedef'd function type to define (or even declare) a function of that
    > >type.

    >
    > >Since the only use of such a typedef is to make a type "pointer to
    > >such a function" I probably will stick to the "typedef int
    > >*pointer_to_such_function(int,int)" syntax in my own code.

    >
    > You probably meant
    >    typedef int (*ptr)(int, int);
    > otherwise the asterisk binds to the int.


    I think I did, yes.

    I copied it from Keith's post:

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


    So I think the parentheses slipped his fingers, too. Or did he mean
    something completely different?
     
    André Hänsel, Mar 24, 2009
    #19
  20. André Hänsel <> writes:
    > On 23 Mrz., 03:01, Barry Schwarz <> wrote:

    [...]
    >> You probably meant
    >>    typedef int (*ptr)(int, int);
    >> otherwise the asterisk binds to the int.

    >
    > I think I did, yes.
    >
    > I copied it from Keith's post:
    >
    >> 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;

    >
    > So I think the parentheses slipped his fingers, too. Or did he mean
    > something completely different?


    No, I just goofed.

    --
    Keith Thompson (The_Other_Keith) <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"
     
    Keith Thompson, Mar 24, 2009
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. johny smith
    Replies:
    7
    Views:
    316
  2. Replies:
    3
    Views:
    434
  3. John Salerno
    Replies:
    3
    Views:
    361
    John Salerno
    May 9, 2006
  4. Oliver Bleckmann
    Replies:
    1
    Views:
    316
    Oliver Bleckmann
    Nov 18, 2006
  5. Angus
    Replies:
    6
    Views:
    328
    Andrey Tarasevich
    Mar 31, 2008
Loading...

Share This Page