struct / typedef confusion

Discussion in 'C Programming' started by Guillaume Dargaud, May 29, 2007.

  1. I just saw the following two lines in /usr/include/usb.h and my head is
    spinning:

    struct usb_dev_handle;
    typedef struct usb_dev_handle usb_dev_handle;

    What is that supposed to mean ?
    I assume the first line is a forward declaration.
    I can't find a definition for it, so does that mean it's like a void ?
    Apparently gdb is confused as well as I can't seem to display anything based
    on this struct.
    --
    Guillaume Dargaud
    http://www.gdargaud.net/Antarctica/Penguins.html
     
    Guillaume Dargaud, May 29, 2007
    #1
    1. Advertising

  2. Guillaume Dargaud wrote:
    > I just saw the following two lines in /usr/include/usb.h and my head is
    > spinning:
    >
    > struct usb_dev_handle;
    > typedef struct usb_dev_handle usb_dev_handle;


    It means that both "struct usb_dev_handle" and the typedef
    "usb_dev_handle" now refer to a struct with a tag of usb_dev_handle,
    but you don't know what is inside that struct.

    But it is enough information to declare for example a function
    returning a pointer to a usb_dev_handle or taking one as an argument.
    Like

    usb_dev_handle* create_usb_dev_handle (void);
    void destroy_usb_dev_handle (usb_dev_handle* h);
    size_t read_from_usb (usb_dev_handle* h, void* buffer, size_t size);

    and now you can write code like

    char buffer [10];
    usb_dev_handle* p = create_usb_dev_handle ();
    read_from_usb (p, buffer, sizeof (buffer));
    destroy_usb_dev_handle (p);

    even though you don't have any idea what's inside the struct.
     
    christian.bau, May 29, 2007
    #2
    1. Advertising

  3. In article <f3hcvo$qfa$2p3.fr>,
    Guillaume Dargaud <> wrote:

    >I just saw the following two lines in /usr/include/usb.h and my head is
    >spinning:


    >struct usb_dev_handle;
    >typedef struct usb_dev_handle usb_dev_handle;


    >What is that supposed to mean ?


    It means that struct usb_dev_handle is a structure of some kind,
    whose contents are undefined to this section of code. "Incomplete"
    declartions such as this are useful when writing library code in
    which the internals of the defined object should be "opaque"
    (known only to the implementation).

    >I assume the first line is a forward declaration.
    >I can't find a definition for it, so does that mean it's like a void ?


    No, not like void, but a pointer to such a structure is akin to
    void* -- a pointer to -something- that will be converted by the
    library code to point to the real structure at need.
    --
    "law -- it's a commodity"
    -- Andrew Ryan (The Globe and Mail, 2005/11/26)
     
    Walter Roberson, May 29, 2007
    #3
  4. > It means that struct usb_dev_handle is a structure of some kind,
    > whose contents are undefined to this section of code. "Incomplete"
    > declartions such as this are useful when writing library code in
    > which the internals of the defined object should be "opaque"
    > (known only to the implementation).


    Thanks both of you. I didn't know this was possible in C, although I've
    known for a long time that it isn't strongly typed.

    Still, isn't there a contradiction in having both a struct and a typedef
    with the same name ?
    --
    Guillaume Dargaud
    http://www.gdargaud.net/Climbing/
     
    Guillaume Dargaud, May 29, 2007
    #4
  5. Guillaume Dargaud

    ais523 Guest

    On May 29, 3:22 pm, "Guillaume Dargaud"
    <> wrote:
    > I just saw the following two lines in /usr/include/usb.h and my head is
    > spinning:
    >
    > struct usb_dev_handle;
    > typedef struct usb_dev_handle usb_dev_handle;
    >
    > What is that supposed to mean ?
    > I assume the first line is a forward declaration.
    > I can't find a definition for it, so does that mean it's like a void ?
    > Apparently gdb is confused as well as I can't seem to display anything based
    > on this struct.

    The line is declaring that a struct with a tag of usb_dev_handle
    exists (which code would refer to as "struct usb_dev_handle"). The
    second line allows a shorter form to be used for it's name (just
    "usb_dev_handle"). Because no information about what's in the struct
    has been given, it's a so-called "incomplete type"; you can pass
    pointers to it around, but not create an object of that type (at least
    not safely, if you don't know how big it is). Normally, there'll be
    some library function around that does know the details of the type
    and which can create objects of that type; however, you have no way to
    access the details yourself without that info, and neither does your
    debugger (if you loaded debug information into it from the library,
    assuming you have that information, it'll be able to display
    information as it would with a complete type).

    void is linked to this, in that it's an incomplete type that cannot be
    completed, and so you can perform the same operations with it, but no
    more:

    struct usb_dev_handle;
    typedef struct usb_dev_handle usb_dev_handle;

    void* a; /* fine */
    usb_dev_handle* b; /* fine */
    void c; /* error */
    usb_dev_handle d; /* error */

    void func(void) /* void has a special meaning here that has nothing
    to do with incomplete types */
    {
    usb_dev_handle e; /* error */
    usb_dev_handle *f; /* fine */
    void g; /* error */
    void *h; /* fine */
    h=malloc(10); /* legal, but probably a bad idea to use a magic
    number here */
    h=malloc(10*sizeof(void)); /* would be safer if it made sense, but
    it doesn't */
    f=malloc(10); /* legal but very stupid, as you have no idea how big
    a
    usb_dev_handle is */
    f=malloc(10*sizeof(*f)); /* error, because the compiler has no idea
    how big a
    usb_dev_handle is either */
    }

    --
    ais523
     
    ais523, May 29, 2007
    #5
  6. Guillaume Dargaud

    Ben Pfaff Guest

    "Guillaume Dargaud" <>
    writes:
    > Still, isn't there a contradiction in having both a struct and a typedef
    > with the same name ?


    It can be confusing to human readers to have a different
    structure with the same struct tag and typedef, but it does not
    confuse the compiler. Struct tags and typedefs are in different
    namespaces: tags appear only immediately after the reserved word
    "struct", and typedef names never do.

    I don't think it's very confusing to give the same structure the
    same struct tag and typedef name, but it's unnecessary. Usually,
    in my code, I don't typedef my structs at all.
    --
    "Am I missing something?"
    --Dan Pop
     
    Ben Pfaff, May 29, 2007
    #6
  7. In article <f3hedp$rtn$2p3.fr>,
    Guillaume Dargaud <> wrote:

    >Still, isn't there a contradiction in having both a struct and a typedef
    >with the same name ?


    No, C has a few different "name spaces", with a usage in one
    name space not conflicting with the usage in another name space.
    For example, statement labels don't conflict with ordinary
    identifiers. In 30 seconds reading of C89 I'm left uncertain
    exactly which name space is used for typedefs, but the
    tags of structures, unions, and enumerations are specifically
    noted as being disambiguated by the presence of the
    'struct', 'union' or 'enum' tag.
    --
    Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
     
    Walter Roberson, May 29, 2007
    #7
  8. Ben Pfaff <> writes:
    > "Guillaume Dargaud" <>
    > writes:
    >> Still, isn't there a contradiction in having both a struct and a typedef
    >> with the same name ?

    >
    > It can be confusing to human readers to have a different
    > structure with the same struct tag and typedef, but it does not
    > confuse the compiler. Struct tags and typedefs are in different
    > namespaces: tags appear only immediately after the reserved word
    > "struct", and typedef names never do.
    >
    > I don't think it's very confusing to give the same structure the
    > same struct tag and typedef name, but it's unnecessary. Usually,
    > in my code, I don't typedef my structs at all.


    Neither do I in most cases, but this:

    struct usb_dev_handle;
    typedef struct usb_dev_handle usb_dev_handle;

    is a case where using a typedef for a struct actually makes sense.
    The type "usb_dev_handle" is an opaque type; the only thing client
    code needs to know about it is that it's an object type, and you can
    manipulate pointers to it (presumably using functions in the same
    header that take arguments of type usb_dev_handle*). Presumably
    client code will never refer to members of the type, so it doesn't
    need to know that it's a struct.

    There's no real reason to use different identifiers for the struct tag
    and the typedef name; using the same identifier makes it clearer that
    they're really the same thing.

    It's very similar to the handling of type FILE in <stdio.h>. It could
    have been declared as "struct FILE", but using the simple identifier
    "FILE" *deliberately* hides the internals. (Well, it doesn't
    completely hide them, but it expresses the intent that they shouldn't
    be used.)

    On the other hand, if client code is intended to refer to members of
    the structure, then adding a typedef merely creates as second name for
    something that already has a perfectly good name, and purports to hide
    information (the fact that the type is a struct) that really isn't
    hidden at all.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 29, 2007
    #8
  9. On Tue, 29 May 2007 15:51:54 +0000 (UTC), -cnrc.gc.ca
    (Walter Roberson) wrote:

    > In article <f3hedp$rtn$2p3.fr>,
    > Guillaume Dargaud <> wrote:
    >
    > >Still, isn't there a contradiction in having both a struct and a typedef
    > >with the same name ?

    >
    > No, C has a few different "name spaces", with a usage in one
    > name space not conflicting with the usage in another name space.


    Right.

    > For example, statement labels don't conflict with ordinary
    > identifiers. In 30 seconds reading of C89 I'm left uncertain
    > exactly which name space is used for typedefs, but the


    The 'ordinary identifier' namespace, which also contains (named)
    objects (aka variables), functions, and enum constants.

    > tags of structures, unions, and enumerations are specifically
    > noted as being disambiguated by the presence of the
    > 'struct', 'union' or 'enum' tag.


    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Jul 1, 2007
    #9
    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. DanielEKFA
    Replies:
    8
    Views:
    641
    DanielEKFA
    May 16, 2005
  2. Chris Fogelklou
    Replies:
    36
    Views:
    1,438
    Chris Fogelklou
    Apr 20, 2004
  3. Steven T. Hatton
    Replies:
    2
    Views:
    697
  4. oor
    Replies:
    0
    Views:
    1,412
  5. arnuld

    Confusion on typedef functions

    arnuld, Mar 18, 2009, in forum: C Programming
    Replies:
    4
    Views:
    5,340
    Ben Bacarisse
    Mar 18, 2009
Loading...

Share This Page