Thread: Simplify complex declarations using typedef.

  1. #1
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357

    Simplify complex declarations using typedef.

    Hello to all. I have some complex declarations to simplify with typedef I have done a try

    1.
    Code:
     
    char (*x[10]) (int);
    
    /* typedef char FUNC(int);
       typedef FUNC *FUNC_PTR;
       FUNC_PTR x[10]; */
    Why we don't use * symbol in the last statement in front of FUNC_PTR?

    2.
    Code:
     
    int (*x(int))[5]
    I can't do this :/

    3.
    Code:
    float *(*x(void))(int); 
    
    /* typedef float *FUNC(int);
        FUNC *x(void); */
    I have no way to see if I am right could you test my answers? and help me with the second? thank you
    Last edited by Mr.Lnx; 01-02-2014 at 05:39 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Seems silly, and it hasn't quite stuck in my head, but: C Right-Left Rule (Rick Ord's CSE 30 - UC San Diego)

    And given that there exists a tool for unwinding declarations (and typedefs) into a type (cdecl) (originally command line, but now on the web!) you've got a way to check.

  3. #3
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Quote Originally Posted by tabstop View Post
    Seems silly, and it hasn't quite stuck in my head, but: C Right-Left Rule (Rick Ord's CSE 30 - UC San Diego)

    And given that there exists a tool for unwinding declarations (and typedefs) into a type (cdecl) (originally command line, but now on the web!) you've got a way to check.
    You mean this

    cdecl: C gibberish ↔ English

    It doesn't take examples with typedef (syntax error).

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by tabstop View Post
    Seems silly, and it hasn't quite stuck in my head, but: C Right-Left Rule (Rick Ord's CSE 30 - UC San Diego)
    That guy was my prof for that exact class, quite some years ago! Silly though it seems, I still remember that rule. Very good prof/class.

    Here's another good explanation of how to read C declarations: Reading C type declarations.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    To figure them out, start at the identifier and follow the precedence rules outwards. The main thing to remember about precedence here is that () and [] (function parens and array brackets) have the highest precedence. Of course, regular parens are used to alter this.
    Code:
    char (*x[10]) (int);
    /*
    x              x is 
    []             an array (of 10 elements)
    *              of pointers
    ()             to functions (taking int)
    char           returning char
    */
    typedef char(*FUNC)(int);
    FUNC x1[10];
    
    
    int (*x2(int))[5];
    /*
    x           x is
    ()          a function (taking int)
    *           returning a pointer
    []          to an array (of 5 elements)
    int         of int
    */
    typedef int (*ARRAY)[5];
    ARRAY x3(int);
    
    
    float *(*x4(void))(int); 
    /*
    x              x is
    ()             a function (taking void)
    *              returning a pointer
    ()             to a function (taking an int)
    *              returning a pointer
    float          to a float
    */
    typedef float*(*FUNC2)(int);
    FUNC2 x5(void);
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Mr.Lnx View Post
    Hello to all. I have some complex declarations to simplify with typedef I have done a try

    1.
    Code:
     
    char (*x[10]) (int);
    
    /* typedef char FUNC(int);
       typedef FUNC *FUNC_PTR;
       FUNC_PTR x[10]; */
    Why we don't use * symbol in the last statement in front of FUNC_PTR?
    Because you can't have a * as the left-most symbol in a declaration.
    The way you were talking about it would expand to something like:
    *char (*x[10]) (int);
    Which is not valid C syntax

    The * symbol is embedded in the definition of FUNC_PTR (which is a FUNC *). Note, this has something to do with operator precedence. The [10] is processed before the *. Expand it one layer at a time
    x is an array of 10 FUNC_PTRs
    x is an array of 10 (pointer to FUNC or FUNC *) -- there is your *
    x is an array of 10 (pointer to (function taking int and returning char))

    Quote Originally Posted by Mr.Lnx View Post
    3.
    Code:
    float *(*x(void))(int); 
    
    /* typedef float *FUNC(int);
        FUNC *x(void); */
    Those appear to be the same. What makes you think they aren't? If they truly are the same, then you can redeclare x as both types (the typedef'ed and non-typedef'ed) and the compiler shouldn't care. When I compile the following program, I get no errors:
    Code:
    $ cat foo.c
    typedef float *FUNC(int);
    
    
    int main(void)
    {
        float *(*x(void))(int);
        FUNC *x(void);
    
    
        return 0;
    }
    $ make foo
    gcc -Wall -ggdb3 -pedantic -std=c99 -O0 -o foo foo.c -lm -lpthread -lrt
    $
    But if I make a small change to FUNC, so it returns float instead of float *, I get the following error:
    Code:
    $ cat foo.c
    typedef float FUNC(int);
    
    
    int main(void)
    {
        float *(*x(void))(int);
        FUNC *x(void);
    
    
        return 0;
    }
    $ make foo
    gcc -Wall -ggdb3 -pedantic -std=c99 -O0 -o foo foo.c -lm -lpthread -lrt
    foo.c: In function ‘main’:
    foo.c:6:11: error: conflicting types for ‘x’
    foo.c:5:14: note: previous declaration of ‘x’ was here
    make: *** [foo] Error 1
    EDIT: I don't know if you actually had a question about your number 2.
    Code:
    int (*x(int))[5]
    If it's giving you problems, you may be missing a semicolon at the end (or you just didn't copy it)
    Last edited by anduril462; 01-02-2014 at 06:50 PM. Reason: added comment re: example #2

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Throwing my $.02 in the ring as well: https://cboard.cprogramming.com/showthread.php?p=1164489

  8. #8
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    @anduril thank you. So I was right =D

    Yes now it is clear!

    I have seen the following :

    Code:
    int *(*x[10])(void);
    
    typedef int *Fcn(void);
    typedef Fcn *Fcn_ptr;
    typedef Fcn_ptr Fcn_ptr_array[10];
    Fcn_ptr_array x;
    I think it can be with less statements as ogabooga wrote you can use one typedef to simplify a complex declaration at the same who some other can use two statements or more typedef's

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-01-2014, 03:24 PM
  2. Can someone help me simplify this?
    By Shackdaddy836 in forum C Programming
    Replies: 1
    Last Post: 10-07-2011, 02:56 PM
  3. Replies: 5
    Last Post: 06-26-2008, 05:07 AM
  4. simplify this?
    By markg in forum C Programming
    Replies: 2
    Last Post: 10-25-2005, 08:09 PM
  5. Complex declarations & ?error in Kernighan/Ritchie?
    By zzzaaahhh in forum C Programming
    Replies: 6
    Last Post: 10-04-2004, 04:24 PM