Typedef structs

Discussion in 'C Programming' started by stephen henry, Aug 27, 2004.

  1. Hi all,

    I have a question that I'm having difficulty answering. If I have a
    struct:

    typedef struct my_struct_tag{

    struct my_other_struct *other;

    } my_struct_tag

    (I'm using the struct when declaring other because the definition of
    my_other_struct is in another source file.)

    Then, I want to access, from a different source file,

    my_struct *tmp;
    my_other_struct *other_struct;

    tmp->other = other_struct;

    But, for me, this gives a warning saying that the assignment assigns
    different pointer types. If I change the code to:

    tmp->other = (struct my_other_struct *)other_struct;

    It works, but this is fugly. Is there anyway to assign like the first
    method (ie without the cast).

    Thanks,

    Stephen Henry
     
    stephen henry, Aug 27, 2004
    #1
    1. Advertising

  2. stephen henry

    Michael Mair Guest

    Hi,


    I am not sure whether I understand your problem;
    if I do

    > cat os.h

    struct os {int c;};

    > cat s.h

    typedef struct s {struct os *optr;} s_t;

    > cat test.c

    #include "s.h"
    #include "os.h"

    int main (void)
    {
    s_t S, *pS;
    struct os OS, *pOS;

    pOS = &OS;
    pS = &S;
    pS->optr = pOS;

    return 0;
    }

    then test.c compiles even without warning, irrespective
    of the order of the #includes or the fact whether I use
    s or s_t for the typedef. (gcc -Wall -ansi -pedantic test.c)

    How does you setup differ from the above?


    Cheers,
    Michael
     
    Michael Mair, Aug 27, 2004
    #2
    1. Advertising

  3. stephen henry

    Eric Sosman Guest

    stephen henry wrote:
    > Hi all,
    >
    > I have a question that I'm having difficulty answering. If I have a
    > struct:
    >
    > typedef struct my_struct_tag{
    >
    > struct my_other_struct *other;
    >
    > } my_struct_tag
    >
    > (I'm using the struct when declaring other because the definition of
    > my_other_struct is in another source file.)
    >
    > Then, I want to access, from a different source file,
    >
    > my_struct *tmp;
    > my_other_struct *other_struct;
    >
    > tmp->other = other_struct;
    >
    > But, for me, this gives a warning saying that the assignment assigns
    > different pointer types. If I change the code to:
    >
    > tmp->other = (struct my_other_struct *)other_struct;
    >
    > It works, but this is fugly. Is there anyway to assign like the first
    > method (ie without the cast).


    In some times and places, Royalty were considered to
    be semi-divine, out of the general run of mankind (no doubt
    the Royals encouraged this notion). Since it would be an
    unthinkable sacrilege for a mere commoner to lay hands upon
    the Royal person, some difficulty arose when there was
    sickness or injury at the palace: How could the skilled
    medicine man or barber-surgeon conduct a physical examination
    of the ailing ruler without touching him?

    The solution was to use a stand-in. The untouchable
    Majesty would describe his symptoms to a common companion,
    and the companion would submit to the specialist's examination
    while doing his best to imitate his King's complaint. Given
    the state of the medical arts and sciences of the time this
    curious practice may not have made much practical difference
    in the outcome, but today's doctors and nurses might be just
    a wee bit hampered by such a roundabout and indirect custom,
    don't you think?

    The point of this story is that the pseudo-code you've
    shown is just like the stand-in commoner. Is there something
    untouchably holy about your actual code that prevents you from
    revealing it to our unwashed gaze? Personally, I find it
    surpassingly difficult to diagnose your problem when all I get
    to see is your proxy. Please post a *complete* and *minimal*
    example of *actual* code.

    "A King of autocratic power We,
    A despot whose tyrannic will is law,
    Whose rule is paramount o'er land and sea,
    A Presence of unutterable awe!
    But though the awe that I inspire
    Must shrivel with imperial fire
    All foes whom it may chance to touch,
    To judge by what I see and hear,
    It does not seem to interfere
    With popular enjoyment, much."

    -- Paramount, Rex

    --
     
    Eric Sosman, Aug 27, 2004
    #3
  4. stephen henry

    xarax Guest

    "stephen henry" <> wrote in message
    news:...
    > Hi all,
    >
    > I have a question that I'm having difficulty answering. If I have a
    > struct:
    >
    > typedef struct my_struct_tag{
    >
    > struct my_other_struct *other;
    >
    > } my_struct_tag
    >
    > (I'm using the struct when declaring other because the definition of
    > my_other_struct is in another source file.)
    >
    > Then, I want to access, from a different source file,
    >
    > my_struct *tmp;
    > my_other_struct *other_struct;


    You probably want that line to say:

    struct my_other_struct *other_struct;
    ^^^^^^

    That is, you forgot the "struct" keyword.

    > tmp->other = other_struct;
    >
    > But, for me, this gives a warning saying that the assignment assigns
    > different pointer types. If I change the code to:
    >
    > tmp->other = (struct my_other_struct *)other_struct;
    >
    > It works, but this is fugly. Is there anyway to assign like the first
    > method (ie without the cast).
    >
    > Thanks,
    >
    > Stephen Henry



    --
    ----------------------------
    Jeffrey D. Smith
    Farsight Systems Corporation
    24 BURLINGTON DRIVE
    LONGMONT, CO 80501-6906
    http://www.farsight-systems.com
    z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
     
    xarax, Aug 27, 2004
    #4
  5. write a "typedef struct my_other_struct *my_other_struct_ptr;"
    before you declare the code typedef struct my_struct_tag { ...} ...;

    this is doubly-independent definition. C actually allows typedef of a
    struct pointer (pointer only) without knowing the definition.

    chok


    stephen henry wrote:

    > Hi all,
    >
    > I have a question that I'm having difficulty answering. If I have a
    > struct:
    >
    > typedef struct my_struct_tag{
    >
    > struct my_other_struct *other;
    >
    > } my_struct_tag
    >
    > (I'm using the struct when declaring other because the definition of
    > my_other_struct is in another source file.)
    >
    > Then, I want to access, from a different source file,
    >
    > my_struct *tmp;
    > my_other_struct *other_struct;
    >
    > tmp->other = other_struct;
    >
    > But, for me, this gives a warning saying that the assignment assigns
    > different pointer types. If I change the code to:
    >
    > tmp->other = (struct my_other_struct *)other_struct;
    >
    > It works, but this is fugly. Is there anyway to assign like the first
    > method (ie without the cast).
    >
    > Thanks,
    >
    > Stephen Henry
     
    ChokSheak Lau, Aug 27, 2004
    #5
  6. "doubly-dependent", not "doubly-independent". my bad.

    chok

    ChokSheak Lau wrote:

    > write a "typedef struct my_other_struct *my_other_struct_ptr;"
    > before you declare the code typedef struct my_struct_tag { ...} ...;
    >
    > this is doubly-independent definition. C actually allows typedef of a
    > struct pointer (pointer only) without knowing the definition.
    >
    > chok
    >
    >
    > stephen henry wrote:
    >
    >> Hi all,
    >>
    >> I have a question that I'm having difficulty answering. If I have a
    >> struct:
    >>
    >> typedef struct my_struct_tag{
    >>
    >> struct my_other_struct *other;
    >>
    >> } my_struct_tag
    >>
    >> (I'm using the struct when declaring other because the definition of
    >> my_other_struct is in another source file.)
    >>
    >> Then, I want to access, from a different source file,
    >> my_struct *tmp;
    >> my_other_struct *other_struct;
    >>
    >> tmp->other = other_struct;
    >>
    >> But, for me, this gives a warning saying that the assignment assigns
    >> different pointer types. If I change the code to:
    >>
    >> tmp->other = (struct my_other_struct *)other_struct;
    >>
    >> It works, but this is fugly. Is there anyway to assign like the first
    >> method (ie without the cast).
    >>
    >> Thanks,
    >>
    >> Stephen Henry
     
    ChokSheak Lau, Aug 27, 2004
    #6
  7. "xarax" <> wrote in message news:<GPHXc.124$w%>...
    > "stephen henry" <> wrote in message
    > news:...
    > > Hi all,
    > >
    > > I have a question that I'm having difficulty answering. If I have a
    > > struct:
    > >
    > > typedef struct my_struct_tag{
    > >
    > > struct my_other_struct *other;
    > >
    > > } my_struct_tag
    > >
    > > (I'm using the struct when declaring other because the definition of
    > > my_other_struct is in another source file.)
    > >
    > > Then, I want to access, from a different source file,
    > >
    > > my_struct *tmp;
    > > my_other_struct *other_struct;

    >
    > You probably want that line to say:
    >
    > struct my_other_struct *other_struct;
    > ^^^^^^
    >
    > That is, you forgot the "struct" keyword.


    Sorry, but I need to clarify somewhat:

    Say I have two structures in two seperate files

    file1.c
    -------

    typedef struct my_structure1_tag {

    // FOO;

    } my_structure1;

    file2.c
    -------

    typedef struct my_structure2_tag {

    my_structure1 *my_struct;

    } my_structure2;

    Now, in order to get file2.c to compile I have to change it so that it
    reads:

    typedef struct my_structure2_tag {

    STRUCT my_structure1 *my_struct;

    } my_structure2;

    Without the STRUCT i would get a syntax error because the compiler has
    not compiled file1.c (which contains the decleration of
    my_structure1). By inserting STRUCT I'm essentially saying to the
    compiler that my_struct is a pointer to a structure, but I've not yet
    defined what that structure actually is yet. What I would like to do,
    would be to assigned a newly created my_structure1 as follows:

    my_structure1 *structure1;
    my_structure2 *structure2;

    structure1->my_struct = structure2;

    However, because in structure2, my_struct is declares as STRUCT
    my_structure1 I have to cast the above assignment to:

    structure1->my_struct = (struct my_structure1 *)structure2;

    If I don't do this cast, I would get an error saying that I'm
    assigning two incompatible pointer types.

    So the question is: Is there anyway to compile C such that a structure
    can contain another -I believe its called an incomplete- structure
    from another, not yet compiled file, without having to cast in the
    above manner.

    Thanks,

    Stephen Henry
     
    stephen henry, Aug 27, 2004
    #7
  8. stephen henry

    Michael Mair Guest

    Hiho,

    > file1.c
    > -------
    >
    > typedef struct my_structure1_tag {
    >
    > // FOO;
    >
    > } my_structure1;


    --> file1.h
    >
    > file2.c
    > -------

    #include "file1.h"
    >
    > typedef struct my_structure2_tag {
    >
    > my_structure1 *my_struct;

    without the #include, this type is not known.

    >
    > } my_structure2;
    >
    > Now, in order to get file2.c to compile I have to change it so that it
    > reads:
    >
    > typedef struct my_structure2_tag {
    >
    > STRUCT my_structure1 *my_struct;

    with the #include, both ways are possible; this shoul
    read struct. If you want to mark something, use a comment.
    >
    > } my_structure2;


    it would be better, to put that typedef into file2.h (which
    includes file1.h).
    >
    > Without the STRUCT i would get a syntax error because the compiler has
    > not compiled file1.c (which contains the decleration of
    > my_structure1). By inserting STRUCT I'm essentially saying to the
    > compiler that my_struct is a pointer to a structure, but I've not yet
    > defined what that structure actually is yet. What I would like to do,
    > would be to assigned a newly created my_structure1 as follows:
    >
    > my_structure1 *structure1;
    > my_structure2 *structure2;
    >
    > structure1->my_struct = structure2;


    That is not possible. structure1 only contains // FOO;

    > However, because in structure2, my_struct is declares as STRUCT
    > my_structure1 I have to cast the above assignment to:
    >
    > structure1->my_struct = (struct my_structure1 *)structure2;
    >
    > If I don't do this cast, I would get an error saying that I'm
    > assigning two incompatible pointer types.


    In which file are you doing this, file1.c, file2.c, or some
    yet unknown file3.c?

    > So the question is: Is there anyway to compile C such that a structure
    > can contain another -I believe its called an incomplete- structure
    > from another, not yet compiled file, without having to cast in the
    > above manner.


    If I understand you correctly, try whether
    struct mystructure1;

    typedef struct my_structure2_tag {
    struct my_structure1 *my_struct;
    } my_structure2;
    helps you.


    You have been asked -- directly and indirectly -- to post
    a minimal example. Please do not use Pseudo-Code, as this is
    likely to produce more confusion than clarifying; apart from
    that, yours is broken.

    Some notes:
    - Use header files for your types, #defines, prototypes and so on.

    - Take the time to bring the example down to a minimal example
    you can post here (c.f. my first answer to your question).

    - Do not tell us what you think happens but give us actual code.


    --
    Michael
     
    Michael Mair, Aug 27, 2004
    #8
  9. stephen henry

    Michael Mair Guest

    Hiho,

    > file1.c
    > -------
    >
    > typedef struct my_structure1_tag {
    >
    > // FOO;
    >
    > } my_structure1;


    --> file1.h
    >
    > file2.c
    > -------

    #include "file1.h"
    >
    > typedef struct my_structure2_tag {
    >
    > my_structure1 *my_struct;

    without the #include, this type is not known.

    >
    > } my_structure2;
    >
    > Now, in order to get file2.c to compile I have to change it so that it
    > reads:
    >
    > typedef struct my_structure2_tag {
    >
    > STRUCT my_structure1 *my_struct;

    with the #include, both ways are possible; this shoul
    read struct. If you want to mark something, use a comment.
    >
    > } my_structure2;


    it would be better, to put that typedef into file2.h (which
    includes file1.h).
    >
    > Without the STRUCT i would get a syntax error because the compiler has
    > not compiled file1.c (which contains the decleration of
    > my_structure1). By inserting STRUCT I'm essentially saying to the
    > compiler that my_struct is a pointer to a structure, but I've not yet
    > defined what that structure actually is yet. What I would like to do,
    > would be to assigned a newly created my_structure1 as follows:
    >
    > my_structure1 *structure1;
    > my_structure2 *structure2;
    >
    > structure1->my_struct = structure2;


    That is not possible. structure1 only contains // FOO;

    > However, because in structure2, my_struct is declares as STRUCT
    > my_structure1 I have to cast the above assignment to:
    >
    > structure1->my_struct = (struct my_structure1 *)structure2;
    >
    > If I don't do this cast, I would get an error saying that I'm
    > assigning two incompatible pointer types.


    In which file are you doing this, file1.c, file2.c, or some
    yet unknown file3.c?

    > So the question is: Is there anyway to compile C such that a structure
    > can contain another -I believe its called an incomplete- structure
    > from another, not yet compiled file, without having to cast in the
    > above manner.


    If I understand you correctly, try whether
    struct mystructure1;

    typedef struct my_structure2_tag {
    struct my_structure1 *my_struct;
    } my_structure2;
    (untested) helps you.


    You have been asked -- directly and indirectly -- to post
    a minimal example. Please do not use Pseudo-Code, as this is
    likely to produce more confusion than clarifying; apart from
    that, yours is broken.

    Some notes:
    - Use header files for your types, #defines, prototypes and so on.

    - Take the time to bring the example down to a minimal example
    you can post here (c.f. my first answer to your question).

    - Do not tell us what you think happens but give us actual code.


    --
    Michael
     
    Michael Mair, Aug 27, 2004
    #9
  10. stephen henry

    Chris Torek Guest

    In article <news:>
    stephen henry <> wrote:
    >Sorry, but I need to clarify somewhat:


    [more sample code that is definitely not the actual code]

    Suppose you were a car mechanic and I drove up in a vehicle and
    said "my car isn't working right; it won't start." You might wonder
    how I got the car to you. What would you think if I told you: "Oh,
    this isn't my car, this is my neighbor's car, but we have the same
    brand of vehicle. You should be able to fix mine by looking at
    his, right?"

    :)

    In any case, I have a method I recommend. Stop using typedef for
    structs.

    Just plain stop using it. You do not NEED it, and what it does is
    rarely what most beginning or even intermediate-level C programmers
    expect. Use structure tags, and most of your problems will go
    away.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Aug 27, 2004
    #10
  11. stephen henry

    Tim Rentsch Guest

    Chris Torek <> writes:

    > In any case, I have a method I recommend. Stop using typedef for
    > structs.
    >
    > Just plain stop using it. You do not NEED it, and what it does is
    > rarely what most beginning or even intermediate-level C programmers
    > expect. Use structure tags, and most of your problems will go
    > away.


    Usually I find myself in agreement with Chris Torek's advice;
    in this case however I think the advice given is somewhat
    shortsighted.

    Right from the very beginning, C programmers should be taught
    to follow the pattern


    typedef struct some_type_name_struct_tag some_type_name;


    struct some_type_name_struct_tag {

    /* ... definition goes here ... */

    };


    and elsewhere always use 'some_type_name' to refer to the structure
    type.

    I don't mean to suggest that they follow the pattern blindly; there
    should be explanation of the two pieces. But the amount of
    explanation needed isn't that much, and the development practice is a
    good one to be in the habit of following. Surely at some point there
    will also be a need to explain about 'struct' tags and their separate
    namespace, and so forth, but the pattern above is helpful much more
    often than it's harmful - it's better to learn it earlier rather than
    later.
     
    Tim Rentsch, Aug 30, 2004
    #11
  12. stephen henry

    pete Guest

    Tim Rentsch wrote:
    >
    > Chris Torek <> writes:
    >
    > > In any case, I have a method I recommend. Stop using typedef for
    > > structs.
    > >
    > > Just plain stop using it. You do not NEED it, and what it does is
    > > rarely what most beginning or even intermediate-level C programmers
    > > expect. Use structure tags, and most of your problems will go
    > > away.

    >
    > Usually I find myself in agreement with Chris Torek's advice;
    > in this case however I think the advice given is somewhat
    > shortsighted.
    >
    > Right from the very beginning, C programmers should be taught
    > to follow the pattern
    >
    > typedef struct some_type_name_struct_tag some_type_name;
    >
    > struct some_type_name_struct_tag {
    >
    > /* ... definition goes here ... */
    >
    > };
    >
    > and elsewhere always use 'some_type_name' to refer to the structure
    > type.
    >
    > I don't mean to suggest that they follow the pattern blindly; there
    > should be explanation of the two pieces. But the amount of
    > explanation needed isn't that much, and the development practice is a
    > good one to be in the habit of following. Surely at some point there
    > will also be a need to explain about 'struct' tags and their separate
    > namespace, and so forth, but the pattern above is helpful much more
    > often than it's harmful - it's better to learn it earlier rather than
    > later.


    Your explanation is missing the part about why it's good
    to typedef a struct. I don't see any point in doing it.
    Why is
    some_type_name object;
    superior to
    struct some_type_name_struct_tag object;
    ?

    --
    pete
     
    pete, Aug 30, 2004
    #12
  13. stephen henry

    Chris Torek Guest

    >> Chris Torek <> writes:
    >>> In any case, I have a method I recommend. Stop using typedef for
    >>> structs. ...


    >Tim Rentsch wrote:
    >> Usually I find myself in agreement with Chris Torek's advice;
    >> in this case however I think the advice given is somewhat
    >> shortsighted.
    >>
    >> Right from the very beginning, C programmers should be taught
    >> to follow the pattern
    >>
    >> typedef struct some_type_name_struct_tag some_type_name;
    >>
    >> struct some_type_name_struct_tag {
    >>
    >> /* ... definition goes here ... */
    >>
    >> };
    >>
    >> and elsewhere always use 'some_type_name' to refer to the structure
    >> type.


    This is what I recommend as an alternative *if* one is stubbornly
    insistent on using typedefs.

    >> I don't mean to suggest that they follow the pattern blindly; there
    >> should be explanation of the two pieces.


    And indeed, in the past, I have done that (feel free to DejaGoogle
    search for such articles). Sometimes I have less time to post,
    though. :)

    In article <news:>
    pete <> wrote:
    >Your explanation is missing the part about why it's good
    >to typedef a struct. I don't see any point in doing it.
    >Why is
    > some_type_name object;
    >superior to
    > struct some_type_name_struct_tag object;
    >?


    I do not believe it is, myself, but I acknowledge that this is a
    matter of opinion rather than fact.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Aug 30, 2004
    #13
  14. stephen henry

    Tim Rentsch Guest

    pete <> writes:

    > Tim Rentsch wrote:


    > > Right from the very beginning, C programmers should be taught
    > > to follow the pattern
    > >
    > > typedef struct some_type_name_struct_tag some_type_name;
    > >
    > > struct some_type_name_struct_tag {
    > >
    > > /* ... definition goes here ... */
    > >
    > > };
    > >
    > > and elsewhere always use 'some_type_name' to refer to the structure
    > > type.

    >
    > Your explanation is missing the part about why it's good
    > to typedef a struct. I don't see any point in doing it.
    > Why is
    > some_type_name object;
    > superior to
    > struct some_type_name_struct_tag object;
    > ?


    Ahh, this is a good question. I would offer several reasons:

    1. (minor) Slight economy of expression - shorter to omit 'struct'.

    2. Using a typedef'ed name gives greater flexibility in the choice
    of type - if later we want some_type_name to be a 'union' or 'int'
    or 'enum', less of the program will need to change as a result.

    3. Greater safety - if the type is defined in a header file (as it
    very likely may be), and the header file is not #include'ed, using

    some_type_name *x;

    will produce an error, whereas

    struct some_type_name_struct_tag *x;

    need no produce any diagnostic at all. Sometimes the second case is
    perfectly easy to figure out, but the first case is *always* easy to
    figure out.

    4. Natural extension to opaque types - a commonly useful pattern is to
    pass pointers where the pointer type is public but the type being
    pointed at is private; if someone is used to separate definitions for
    the type name and the 'struct' members, that leap will seem more
    natural than if they aren't - just move the typedef to a public header
    file and keep the struct definition local. In a sense this point is
    similar to point (2), but there is also something else - for didactic
    reasons we would like to be able introduce opaque types early in the
    educational cycle, and having separately defined type names makes it
    easier both to make use of opaque (pointer) types and to explain some
    mechanics about how to express opaque types in C.

    In connection with point 4, for a type that is opaque and will always
    be accessed via pointers, there is nothing wrong with defining a
    pointer type rather than an instance type as the defined type name.
    (Of course it's important to get the conventions right so which is
    which is always clear.)


    Forgive me for not listing these earlier - I'd sort of assumed without
    thinking about it that most long time C developers would be aware of
    all of these already.
     
    Tim Rentsch, Aug 30, 2004
    #14
  15. stephen henry

    Tim Rentsch Guest

    Chris Torek <> writes:

    > In article <news:>
    > pete <> wrote:
    > >Your explanation is missing the part about why it's good
    > >to typedef a struct. I don't see any point in doing it.
    > >Why is
    > > some_type_name object;
    > >superior to
    > > struct some_type_name_struct_tag object;
    > >?

    >
    > I do not believe it is, myself, but I acknowledge that this is a
    > matter of opinion rather than fact.


    To be fair here, I should say that in addition to some advantages that
    the first form has (which I posted separately), there also are some
    advantages to the second form. I think everyone would agree that
    there are some advantages to each approach; where opinions might
    differ is on the relative merits of the two sets of advantages. My
    other posting didn't try to address either the advantages of the
    second form or the question of the relative merits of the two
    approaches.
     
    Tim Rentsch, Aug 30, 2004
    #15
  16. Tim Rentsch <> writes:
    [...]
    > Right from the very beginning, C programmers should be taught
    > to follow the pattern
    >
    >
    > typedef struct some_type_name_struct_tag some_type_name;
    >
    >
    > struct some_type_name_struct_tag {
    >
    > /* ... definition goes here ... */
    >
    > };
    >
    >
    > and elsewhere always use 'some_type_name' to refer to the structure
    > type.


    The counterargument is that it hides (or attempts to hide) information
    that shouldn't be hidden.

    Assigning a simple name to a complicated type can be useful if the
    goal is data abstraction. It can encourage the programmer to focus on
    the operations that are appropriate to the type, without worrying
    about the lower level operations that may not be. An example of this
    is size_t; the name doesn't tell you whether it's signed, unsigned, or
    floating-point, and the programmer shouldn't write code that depends
    on such details.

    For a struct type, however, there's often not much you can do with the
    type without knowing that it's a struct. If you're going to refer to
    members, you obviously *have* to know that it's a struct. (The type
    FILE in <stdio.h> is an exception to this; the user of the interface
    can use it only via pointers, and there are no portably defined
    members.)

    A good rule of thumb is probably:

    If you can sensibly hide from the user the fact that a type is a
    struct, use a typedef (such as FILE in <stdio.h>). If not, don't, and
    let the user refer to the type as "struct foo" (such as struct tm in
    <time.h>). The latter is probably more common.

    (Personally, I'm not as opposed to gratuitous typedefs for structs as
    some people are, but I understand the arguments.)

    --
    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.
     
    Keith Thompson, Aug 30, 2004
    #16
  17. stephen henry

    pete Guest

    Keith Thompson wrote:

    > Assigning a simple name to a complicated type can be useful if the
    > goal is data abstraction. It can encourage the programmer to focus on
    > the operations that are appropriate to the type, without worrying
    > about the lower level operations that may not be. An example of this
    > is size_t; the name doesn't tell you whether it's signed, unsigned, or
    > floating-point, and the programmer shouldn't write code that depends
    > on such details.


    The programmer can depend on size_t being an unsigned integer type.

    --
    pete
     
    pete, Aug 30, 2004
    #17
  18. pete <> writes:
    > Keith Thompson wrote:
    > > Assigning a simple name to a complicated type can be useful if the
    > > goal is data abstraction. It can encourage the programmer to focus on
    > > the operations that are appropriate to the type, without worrying
    > > about the lower level operations that may not be. An example of this
    > > is size_t; the name doesn't tell you whether it's signed, unsigned, or
    > > floating-point, and the programmer shouldn't write code that depends
    > > on such details.

    >
    > The programmer can depend on size_t being an unsigned integer type.


    Sorry, that was a braino. I meant time_t, not size_t.

    But that raises a good point. C's type system isn't as expressive as
    it could be (which is not to say that it *should* be as expressive as
    it could be). You can have a type name that doesn't tell you anything
    about a type (foo_t), or one that tells you only that it's a struct
    (struct foo), but there's no syntax for specifying that time_t is an
    arithmetic type, or that size_t is an unsigned integer type without
    saying which one. In many cases, you have to depend on documentation
    to let the programmer know what properties can be depended on.

    Any convention about whether to use "struct foo" or a typedef is going
    to be an imperfect compromise.

    --
    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.
     
    Keith Thompson, Aug 30, 2004
    #18
  19. stephen henry

    Ben Pfaff Guest

    pete <> writes:

    > Your explanation is missing the part about why it's good
    > to typedef a struct. I don't see any point in doing it.
    > Why is
    > some_type_name object;
    > superior to
    > struct some_type_name_struct_tag object;


    I generally do not typedef structs. However, occasionally I run
    into an awkward situation where I want one struct to be
    interchangeable for another. For example, suppose one already
    has a linked list whose element is a `struct list_elem'. If one
    then wishes to implement a hash table with chaining it would be
    convenient for abstraction purposes to declare `struct hash_elem'
    as an alias for `struct list_elem'. Unfortunately, this simply
    cannot be done in C. `#define hash_elem list_elem' is not
    acceptable because it pollutes the global namespace, not just the
    tag namespace. A `typedef' is a reasonable way out.
    --
    "It would be a much better example of undefined behavior
    if the behavior were undefined."
    --Michael Rubenstein
     
    Ben Pfaff, Aug 30, 2004
    #19
  20. stephen henry

    Tim Rentsch Guest

    Keith Thompson <> writes:

    > Tim Rentsch <> writes:
    > [...]
    > > Right from the very beginning, C programmers should be taught
    > > to follow the pattern
    > >
    > >
    > > typedef struct some_type_name_struct_tag some_type_name;
    > >
    > >
    > > struct some_type_name_struct_tag {
    > >
    > > /* ... definition goes here ... */
    > >
    > > };
    > >
    > >
    > > and elsewhere always use 'some_type_name' to refer to the structure
    > > type.

    >
    > The counterargument is that it hides (or attempts to hide) information
    > that shouldn't be hidden.

    ^^^^^^^^^
    What reasons would you offer that it shouldn't be hidden? In a separate
    article I responded to another poster's query and listed some advantages
    of the separate type name approach. Could one of the just-use-structs
    advocates respond and list some principal advantages of not using
    a separate type name?


    > Assigning a simple name to a complicated type can be useful if the
    > goal is data abstraction.


    More importantly, information hiding. See the well-known papers
    by David Parnas. Also Brooks's "Mythical Man Month", 20th Anniversary
    Edition.


    > For a struct type, however, there's often not much you can do with the
    > type without knowing that it's a struct. [...]


    Here's a list of things that can be done with (most) complete types,
    without knowing what type they are:

    1. Declare variables of the type (and arrays-of and pointers-to same)
    2. Assign values (and accept parameters and return results)
    3. Pass values to functions, and get values back as results
    4. Take the address with '&'
    5. Use 'sizeof' to get the size, which allows allocation with 'malloc()'

    In C99 that might be all complete object types - I'm unsure about the status
    in C99 of array assignment. Note that the list is more than enough to allow
    useful work to get done, as the 'FILE' example demonstrates.


    > A good rule of thumb is probably:
    >
    > [...]


    Let me suggest this rule: Always use typedefs for structs, except in
    cases where the advantages of not using them outweigh the advantages
    of using them. I've yet to see a statement in this thread about what
    the advantages of not using typedefs for structs are, let alone a
    comparison of the different advantages for the two approaches.


    > (Personally, I'm not as opposed to gratuitous typedefs for structs as
    > some people are, but I understand the arguments.)


    Keith, I'm disappointed. This kind of rhetoric - a content-free
    statement giving a "non-argument" argument, including the emotional
    hook word "gratuitous" - should be below you.
     
    Tim Rentsch, Aug 31, 2004
    #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. Patricia  Van Hise

    structs with fields that are structs

    Patricia Van Hise, Apr 5, 2004, in forum: C Programming
    Replies:
    5
    Views:
    641
    Al Bowers
    Apr 5, 2004
  2. Chris Hauxwell

    const structs in other structs

    Chris Hauxwell, Apr 23, 2004, in forum: C Programming
    Replies:
    6
    Views:
    560
    Chris Hauxwell
    Apr 27, 2004
  3. Paminu
    Replies:
    5
    Views:
    645
    Eric Sosman
    Oct 11, 2005
  4. Daniel Rudy
    Replies:
    15
    Views:
    1,405
    Keith Thompson
    Apr 10, 2006
  5. Tuan  Bui
    Replies:
    14
    Views:
    476
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page