Re: What is better and why?

Discussion in 'C Programming' started by Tim Rentsch, Jun 15, 2013.

  1. Tim Rentsch

    Tim Rentsch Guest

    Keith Thompson <> writes:

    > "paskali" <> writes:
    >> 1st:
    >>
    >> struct person {
    >> char *name;
    >> char *surname;
    >> };

    >
    > That's my own preference. The type has a name "struct person";
    > I don't feel the need to give it another one.


    How this is expressed seems a little funny to me. Does this mean
    you think there is never any reason to give a structure type a
    different name (ie, using typedef)? Or only that there is never
    a _need_ to do so? Or that there usually is not a need to do so?
    Or what?

    >> 2nd:
    >>
    >> typedef struct {
    >> char *name;
    >> char *surnname;
    >> } person;

    >
    > That form is perfectly valid in this simple case. It has the
    > advantage that the type has a name that's a single identifier.
    > But that name doesn't become visible until the end of the
    > declaration -- which means that the struct can't contain a
    > pointer to another object of the same type.
    >
    >> 3th:
    >>
    >> typedef struct person {
    >> char *name;
    >> char *surname;
    >> } person;

    >
    > Also perfectly valid, and it lets you declare a member of type
    > "struct person*". Since typedef names and tag names are in
    > different namespaces (not in the C++ sense of the word
    > "namespace"), it's ok to use the same identifier for both.


    Certainly it is legal. Is it desirable? I'm not sure if
    you're ducking the question or just glossing over what
    you think the answer is.

    > A drawback, IMHO, is that you can only refer to the type as
    > "struct person" inside the declaration, but you're obviously
    > expected to refer to it as "person" once the declaration is
    > complete.


    I'm somewhat surprised you didn't explain one of the common
    idioms for working around this problem, eg,

    struct person;
    typedef struct person person;
    struct person { ... };

    which allows use of the typedef name 'person' when defining
    the contents of the type 'struct person'.

    >> 4th:
    >>
    >> [example having dangerous naming choice, and response, snipped]

    >
    >> ?

    >
    > I prefer the 1st form. Many other people prefer the 3rd, because it
    > gives the type a name that's a single identifier, and you don't need
    > the "struct" keyword every time you refer to it. My own opinion is
    > that making the fact that it's a struct explicit is a good idea --


    This sounds like a circular statement. How is it different from
    saying, "It's better to use the 'struct' form when declaring
    things, becausee it's a good idea for the 'struct' keyword to be
    present in the declaration." How is that not just tautological?

    > unless it's an opaque type such that code should use it without
    > knowing that it's a struct (in particular, not referring to the
    > names of any of its members). Type FILE, defined in <stdio.h>,
    > is an example of an opaque type.


    Discussions about questions of style often lead nowhere. A large
    part of why that's true is people give their conclusions first and
    then give their reasoning/arguments second. It's a bad process.
    When considering a style question, it's better to start with an
    attitude of withholding judgment, and try to list objectively all
    the plusses and minusses of each choice. (Obviously these will
    sometimes be complementary; it's still good to list both.) The
    objective listing of plusses and minusses should be something
    everyone can agree on, as objectively verifiable facts. Then,
    only after the costs and benefits are listed, explain which
    factors are thought to deserve relatively more or less weight.
    Separating out the objective and subjective aspects in this way,
    including especially leading off with the objective aspects, is
    much more likely to yield an illumniting discussion, not to
    mention providing a better example to those who are still learning
    how to form opinions on such issues.
     
    Tim Rentsch, Jun 15, 2013
    #1
    1. Advertising

  2. Tim Rentsch <> writes:
    > Keith Thompson <> writes:
    >> "paskali" <> writes:
    >>> 1st:
    >>>
    >>> struct person {
    >>> char *name;
    >>> char *surname;
    >>> };

    >>
    >> That's my own preference. The type has a name "struct person";
    >> I don't feel the need to give it another one.

    >
    > How this is expressed seems a little funny to me. Does this mean
    > you think there is never any reason to give a structure type a
    > different name (ie, using typedef)? Or only that there is never
    > a _need_ to do so? Or that there usually is not a need to do so?
    > Or what?


    I'm not sure it *means* that, but there is never a *need* to give a
    struct type another name. If the language didn't permit typedefs for
    structs, it would not lose any real expressive power.

    For example, <time.h> defines a type "struct tm". It doesn't define a
    typedef for it. IMHO such a typedef is not necessary, and would not be
    particularly beneficial.

    An advantage of a typedef is that it gives the type a name that's a
    single identifer. I don't see that as a particularly important
    advantage. Others do.

    It does make sense to use a typedef when the type is opaque, i.e., when
    code that uses the type is not expected to be written to depend on the
    fact that the type is a struct. Type FILE is a good example of this;
    it's likely to be a typedef for a struct, but portable code that uses
    type FILE cannot refer to its members or assume that it's a struct.

    >>> 2nd:
    >>>
    >>> typedef struct {
    >>> char *name;
    >>> char *surnname;
    >>> } person;

    >>
    >> That form is perfectly valid in this simple case. It has the
    >> advantage that the type has a name that's a single identifier.
    >> But that name doesn't become visible until the end of the
    >> declaration -- which means that the struct can't contain a
    >> pointer to another object of the same type.
    >>
    >>> 3th:
    >>>
    >>> typedef struct person {
    >>> char *name;
    >>> char *surname;
    >>> } person;

    >>
    >> Also perfectly valid, and it lets you declare a member of type
    >> "struct person*". Since typedef names and tag names are in
    >> different namespaces (not in the C++ sense of the word
    >> "namespace"), it's ok to use the same identifier for both.

    >
    > Certainly it is legal. Is it desirable? I'm not sure if
    > you're ducking the question or just glossing over what
    > you think the answer is.


    I'm not *deliberately* ducking the question, I just didn't feel like
    writing about it at great length. If you're going to define a typedef
    for a struct, IMHO it's better to use the same identifier for the tag
    and the typedef name. I can think of no good reason to make the
    identifiers distinct.

    If you're going to use distinct identifiers, I think you should at least
    follow a consistent convention, such as appending "_t" to the tag name
    to form the typedef name (though I think POSIX reserves identifiers
    ending in "_t" for some purposes).

    >> A drawback, IMHO, is that you can only refer to the type as
    >> "struct person" inside the declaration, but you're obviously
    >> expected to refer to it as "person" once the declaration is
    >> complete.

    >
    > I'm somewhat surprised you didn't explain one of the common
    > idioms for working around this problem, eg,
    >
    > struct person;
    > typedef struct person person;
    > struct person { ... };
    >
    > which allows use of the typedef name 'person' when defining
    > the contents of the type 'struct person'.


    I didn't explain it because I didn't think of it -- not too surprising,
    since I prefer not to use typedefs for structs at all.

    >>> 4th:
    >>>
    >>> [example having dangerous naming choice, and response, snipped]

    >>
    >>> ?

    >>
    >> I prefer the 1st form. Many other people prefer the 3rd, because it
    >> gives the type a name that's a single identifier, and you don't need
    >> the "struct" keyword every time you refer to it. My own opinion is
    >> that making the fact that it's a struct explicit is a good idea --

    >
    > This sounds like a circular statement. How is it different from
    > saying, "It's better to use the 'struct' form when declaring
    > things, becausee it's a good idea for the 'struct' keyword to be
    > present in the declaration." How is that not just tautological?


    Referring to a type as "struct foo" makes it clear to the reader
    that it's a struct type. Referring to it as "foo" does not.
    All else being equal, more clarity is better than less clarity.
    Where's the tautology?

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 16, 2013
    #2
    1. Advertising

  3. Tim Rentsch

    Ian Collins Guest

    Keith Thompson wrote:
    > Tim Rentsch <> writes:
    >> Keith Thompson <> writes:
    >>>
    >>> I prefer the 1st form. Many other people prefer the 3rd, because it
    >>> gives the type a name that's a single identifier, and you don't need
    >>> the "struct" keyword every time you refer to it. My own opinion is
    >>> that making the fact that it's a struct explicit is a good idea --

    >>
    >> This sounds like a circular statement. How is it different from
    >> saying, "It's better to use the 'struct' form when declaring
    >> things, becausee it's a good idea for the 'struct' keyword to be
    >> present in the declaration." How is that not just tautological?

    >
    > Referring to a type as "struct foo" makes it clear to the reader
    > that it's a struct type. Referring to it as "foo" does not.
    > All else being equal, more clarity is better than less clarity.
    > Where's the tautology?


    I'd argue that if you need to add "struct" when referring to a type to
    add clarity, there's something wrong with the code. If the distinction
    is important in the current context (the code accesses members), it
    should be obvious. If the distinction isn't important (the variable is
    effectively opaque), "struct" is nothing more than a distraction.

    --
    Ian Collins
     
    Ian Collins, Jun 16, 2013
    #3
  4. Tim Rentsch

    Öö Tiib Guest

    On Saturday, 15 June 2013 20:36:13 UTC+3, Tim Rentsch wrote:
    > Keith Thompson <> writes:
    > > "paskali" <> writes:
    > >> 3th:
    > >>
    > >> typedef struct person {
    > >> char *name;
    > >> char *surname;
    > >> } person;

    > >
    > > Also perfectly valid, and it lets you declare a member of type
    > > "struct person*". Since typedef names and tag names are in
    > > different namespaces (not in the C++ sense of the word
    > > "namespace"), it's ok to use the same identifier for both.

    >
    > Certainly it is legal. Is it desirable? I'm not sure if
    > you're ducking the question or just glossing over what
    > you think the answer is.


    C++ has for whatever reason chosen to make that typedef
    implicit. Making it explicit is also legal C++. So that variant
    may add convenience when the declaration is included and
    used both in C and C++ code since it is legal in both
    languages and results with same effect in both languages.
     
    Öö Tiib, Jun 16, 2013
    #4
  5. Keith Thompson <> wrote:

    (snip)
    > I'm not sure it *means* that, but there is never a *need* to give a
    > struct type another name. If the language didn't permit typedefs for
    > structs, it would not lose any real expressive power.


    > For example, <time.h> defines a type "struct tm". It doesn't define a
    > typedef for it. IMHO such a typedef is not necessary, and would not be
    > particularly beneficial.


    > An advantage of a typedef is that it gives the type a name that's a
    > single identifer. I don't see that as a particularly important
    > advantage. Others do.


    > It does make sense to use a typedef when the type is opaque, i.e., when
    > code that uses the type is not expected to be written to depend on the
    > fact that the type is a struct. Type FILE is a good example of this;
    > it's likely to be a typedef for a struct, but portable code that uses
    > type FILE cannot refer to its members or assume that it's a struct.


    Yes, I don't normally used typedef on my structs, but I do like
    FILE not being stuct FILE. Then again, how much does typedef
    help over #define?

    -- glen
     
    glen herrmannsfeldt, Jun 16, 2013
    #5
  6. Tim Rentsch

    Ike Naar Guest

    On 2013-06-16, glen herrmannsfeldt <> wrote:
    > Yes, I don't normally used typedef on my structs, but I do like
    > FILE not being stuct FILE. Then again, how much does typedef
    > help over #define?


    typedef works in non-trivial cases where #define doesn't.

    struct thing { int i; double d; };

    typedef struct thing thing, thing2[2];

    thing a_thing;
    thing2 a_thing2;

    How would you do this, using #define instead of typedef?
     
    Ike Naar, Jun 16, 2013
    #6
  7. Tim Rentsch

    Tim Rentsch Guest

    glen herrmannsfeldt <> writes:

    > Keith Thompson <> wrote:
    >
    > (snip)
    >> I'm not sure it *means* that, but there is never a *need* to give a
    >> struct type another name. If the language didn't permit typedefs for
    >> structs, it would not lose any real expressive power.

    >
    >> For example, <time.h> defines a type "struct tm". It doesn't define a
    >> typedef for it. IMHO such a typedef is not necessary, and would not be
    >> particularly beneficial.

    >
    >> An advantage of a typedef is that it gives the type a name that's a
    >> single identifer. I don't see that as a particularly important
    >> advantage. Others do.

    >
    >> It does make sense to use a typedef when the type is opaque, i.e., when
    >> code that uses the type is not expected to be written to depend on the
    >> fact that the type is a struct. Type FILE is a good example of this;
    >> it's likely to be a typedef for a struct, but portable code that uses
    >> type FILE cannot refer to its members or assume that it's a struct.

    >
    > Yes, I don't normally used typedef on my structs, but I do like
    > FILE not being stuct FILE. Then again, how much does typedef
    > help over #define?


    Surely someone as bright as you can discover many or most of
    the important differences, without outside help.
     
    Tim Rentsch, Jun 16, 2013
    #7
  8. Tim Rentsch

    Tim Rentsch Guest

    Ike Naar <> writes:

    > On 2013-06-16, glen herrmannsfeldt <> wrote:
    >> Yes, I don't normally used typedef on my structs, but I do like
    >> FILE not being stuct FILE. Then again, how much does typedef
    >> help over #define?

    >
    > typedef works in non-trivial cases where #define doesn't.
    >
    > struct thing { int i; double d; };
    >
    > typedef struct thing thing, thing2[2];
    >
    > thing a_thing;
    > thing2 a_thing2;
    >
    > How would you do this, using #define instead of typedef?


    Surely the question is meant to ask about using #define
    only for the name of the struct type, not for more
    complicated type constructors like arrays.
     
    Tim Rentsch, Jun 16, 2013
    #8
  9. Tim Rentsch

    Tim Rentsch Guest

    Someone writes:

    > On Saturday, 15 June 2013 20:36:13 UTC+3, Tim Rentsch wrote:
    >> Keith Thompson <> writes:
    >> > "paskali" <> writes:
    >> >> 3th:
    >> >>
    >> >> typedef struct person {
    >> >> char *name;
    >> >> char *surname;
    >> >> } person;
    >> >
    >> > Also perfectly valid, and it lets you declare a member of type
    >> > "struct person*". Since typedef names and tag names are in
    >> > different namespaces (not in the C++ sense of the word
    >> > "namespace"), it's ok to use the same identifier for both.

    >>
    >> Certainly it is legal. Is it desirable? I'm not sure if
    >> you're ducking the question or just glossing over what
    >> you think the answer is.

    >
    > C++ has for whatever reason chosen to make that typedef
    > implicit. Making it explicit is also legal C++. So that
    > variant may add convenience when the declaration is included
    > and used both in C and C++ code since it is legal in both
    > languages and results with same effect in both languages.


    This seems like a non-argument to me. It is also true that

    typedef struct person_structure_tag {
    char *name;
    char *surname;
    } person;

    allows the use of 'person' as a type name in both C and C++.
    Moreover, this form relies less on knowing what the C++ rules
    are for how names of struct types are handled, which clearly
    is an advantage for people coming from a C background.
     
    Tim Rentsch, Jun 16, 2013
    #9
  10. Tim Rentsch

    Tim Rentsch Guest

    Keith Thompson <> writes:

    > Tim Rentsch <> writes:
    >> Keith Thompson <> writes:
    >>> "paskali" <> writes:
    >>>> 1st:
    >>>>
    >>>> struct person {
    >>>> char *name;
    >>>> char *surname;
    >>>> };
    >>>
    >>> That's my own preference. The type has a name "struct person";
    >>> I don't feel the need to give it another one.

    >>
    >> How this is expressed seems a little funny to me. Does this mean
    >> you think there is never any reason to give a structure type a
    >> different name (ie, using typedef)? Or only that there is never
    >> a _need_ to do so? Or that there usually is not a need to do so?
    >> Or what?

    >
    > I'm not sure it *means* that, but there is never a *need* to give a
    > struct type another name. If the language didn't permit typedefs for
    > structs, it would not lose any real expressive power.
    >
    > For example, <time.h> defines a type "struct tm". It doesn't define a
    > typedef for it. IMHO such a typedef is not necessary, and would not be
    > particularly beneficial.
    >
    > An advantage of a typedef is that it gives the type a name that's a
    > single identifer. I don't see that as a particularly important
    > advantage. Others do.
    >
    > It does make sense to use a typedef when the type is opaque, i.e., when
    > code that uses the type is not expected to be written to depend on the
    > fact that the type is a struct. Type FILE is a good example of this;
    > it's likely to be a typedef for a struct, but portable code that uses
    > type FILE cannot refer to its members or assume that it's a struct.


    Let me ask my question(s) more directly. What are the benefits of
    using a typedef name for struct types (as opposed to using 'struct'
    and a tag)? What are the costs? In which cases do the costs (a)
    clearly outweigh the benefits, (b) clearly underweigh the benefits,
    and (c) approximately balance the benefits? The third question is
    meant to elicit opinion, the first two more objective assessments.

    >>>> 2nd:
    >>>>
    >>>> typedef struct {
    >>>> char *name;
    >>>> char *surnname;
    >>>> } person;
    >>>
    >>> That form is perfectly valid in this simple case. It has the
    >>> advantage that the type has a name that's a single identifier.
    >>> But that name doesn't become visible until the end of the
    >>> declaration -- which means that the struct can't contain a
    >>> pointer to another object of the same type.
    >>>
    >>>> 3th:
    >>>>
    >>>> typedef struct person {
    >>>> char *name;
    >>>> char *surname;
    >>>> } person;
    >>>
    >>> Also perfectly valid, and it lets you declare a member of type
    >>> "struct person*". Since typedef names and tag names are in
    >>> different namespaces (not in the C++ sense of the word
    >>> "namespace"), it's ok to use the same identifier for both.

    >>
    >> Certainly it is legal. Is it desirable? I'm not sure if
    >> you're ducking the question or just glossing over what
    >> you think the answer is.

    >
    > I'm not *deliberately* ducking the question, I just didn't feel like
    > writing about it at great length. If you're going to define a typedef
    > for a struct, IMHO it's better to use the same identifier for the tag
    > and the typedef name. I can think of no good reason to make the
    > identifiers distinct.


    The names are in different namespaces; different style rules,
    coding standards, or other considerations, may apply in the
    two cases.

    It may be useful to have the two names be different to reduce the
    possibility of confusion.

    It may be useful to have the two names be different to deliberately
    make it harder to use the other name, eg,

    typedef struct foo_avoid_using_this_struct_tag foo;

    > If you're going to use distinct identifiers, I think you should
    > at least follow a consistent convention, such as appending "_t"
    > to the tag name to form the typedef name (though I think POSIX
    > reserves identifiers ending in "_t" for some purposes).


    Certainly there is some benefit to doing this, but there also
    can be benefit from not necessarily tying the two names together in
    all cases. In either case I don't think it matters very much;
    typically I expect the struct tag would appear on only two or
    three places for those structs having both a tag and a typedef
    name.


    >>> A drawback, IMHO, is that you can only refer to the type as
    >>> "struct person" inside the declaration, but you're obviously
    >>> expected to refer to it as "person" once the declaration is
    >>> complete.

    >>
    >> I'm somewhat surprised you didn't explain one of the common
    >> idioms for working around this problem, eg,
    >>
    >> struct person;
    >> typedef struct person person;
    >> struct person { ... };
    >>
    >> which allows use of the typedef name 'person' when defining
    >> the contents of the type 'struct person'.

    >
    > I didn't explain it because I didn't think of it -- not too surprising,
    > since I prefer not to use typedefs for structs at all.
    >
    >>>> 4th:
    >>>>
    >>>> [example having dangerous naming choice, and response, snipped]
    >>>
    >>>> ?
    >>>
    >>> I prefer the 1st form. Many other people prefer the 3rd, because it
    >>> gives the type a name that's a single identifier, and you don't need
    >>> the "struct" keyword every time you refer to it. My own opinion is
    >>> that making the fact that it's a struct explicit is a good idea --

    >>
    >> This sounds like a circular statement. How is it different from
    >> saying, "It's better to use the 'struct' form when declaring
    >> things, becausee it's a good idea for the 'struct' keyword to be
    >> present in the declaration." How is that not just tautological?

    >
    > Referring to a type as "struct foo" makes it clear to the reader
    > that it's a struct type. Referring to it as "foo" does not.
    > All else being equal, more clarity is better than less clarity.
    > Where's the tautology?


    Oh, but now you're saying something different. Your earlier
    statement didn't say anything about clarity, only about being
    explicit. They are not synonymous.

    Furthermore the idea that adding information necessarily adds
    clarity is, at the very least, subject to debate. If that were
    true, then why not do this:

    struct foo_int_x_double_z {
    int x;
    double z;
    };

    Now we know just from a declaration what members and member types a
    struct has! Obviously this suggestion is meant rhetorically, but I
    hope you can see my point. Including the keyword 'struct' in each
    and every declaration that uses the underlying structure type may
    not necessarily lead to code that is easier to understand, and
    certainly not always significantly easier to understand.

    Also, and perhaps most important, is the point you gloss over:
    "all else being equal". It is precisely because all else is not
    equal that the question is raised. If you don't consider both
    benefits AND costs, and make an effort to weigh one against the
    other, any conclusions reached are unlikely to have much value.
    Do you agree with that? If you don't I'm very curious to hear
    why not.
     
    Tim Rentsch, Jun 16, 2013
    #10
  11. Tim Rentsch

    Ike Naar Guest

    On 2013-06-16, Tim Rentsch <> wrote:
    > Ike Naar <> writes:
    >
    >> On 2013-06-16, glen herrmannsfeldt <> wrote:
    >>> Yes, I don't normally used typedef on my structs, but I do like
    >>> FILE not being stuct FILE. Then again, how much does typedef
    >>> help over #define?

    >>
    >> typedef works in non-trivial cases where #define doesn't.
    >>
    >> struct thing { int i; double d; };
    >>
    >> typedef struct thing thing, thing2[2];
    >>
    >> thing a_thing;
    >> thing2 a_thing2;
    >>
    >> How would you do this, using #define instead of typedef?

    >
    > Surely the question is meant to ask about using #define
    > only for the name of the struct type, not for more
    > complicated type constructors like arrays.


    Okay, but even in the simple case #define is not better
    then typedef. So I would like the re-phrase Glen's question:
    how much does #define help over typedef?
     
    Ike Naar, Jun 16, 2013
    #11
  12. Tim Rentsch

    Öö Tiib Guest

    On Sunday, 16 June 2013 18:15:56 UTC+3, Tim Rentsch wrote:
    > Someone writes:
    > > On Saturday, 15 June 2013 20:36:13 UTC+3, Tim Rentsch wrote:
    > >> Keith Thompson <> writes:
    > >> > "paskali" <> writes:
    > >> >> 3th:
    > >> >>
    > >> >> typedef struct person {
    > >> >> char *name;
    > >> >> char *surname;
    > >> >> } person;
    > >> >
    > >> > Also perfectly valid, and it lets you declare a member of type
    > >> > "struct person*". Since typedef names and tag names are in
    > >> > different namespaces (not in the C++ sense of the word
    > >> > "namespace"), it's ok to use the same identifier for both.
    > >>
    > >> Certainly it is legal. Is it desirable? I'm not sure if
    > >> you're ducking the question or just glossing over what
    > >> you think the answer is.

    > >
    > > C++ has for whatever reason chosen to make that typedef
    > > implicit. Making it explicit is also legal C++. So that
    > > variant may add convenience when the declaration is included
    > > and used both in C and C++ code since it is legal in both
    > > languages and results with same effect in both languages.

    >
    > This seems like a non-argument to me.


    If you have no need to compile it with both compilers or do not
    care if resulting effect is maximally similar then it is non-
    argument.

    > It is also true that
    >
    > typedef struct person_structure_tag {
    > char *name;
    > char *surname;
    > } person;
    >
    > allows the use of 'person' as a type name in both C and C++.


    For me that is also fine. I dislike habit of some compilers
    to discuss "struct person_structure_tag" as result in some
    diagnostics, but that is minor.

    However 'struct person', (that several people said to be their
    favorite form of usage) is not available with this definition
    (it is with "3th" in both languages). I like when interfaces are
    least intrusive when it comes to favorite styles of usage.

    > Moreover, this form relies less on knowing what the C++ rules
    > are for how names of struct types are handled, which clearly
    > is an advantage for people coming from a C background.


    If it is interface that is meant for usage in both languages
    (possibly by third parties with unknown taste in style) then the
    better the authors know both languages the easier to everybody.
    If it is not such interface then it does not matter.
     
    Öö Tiib, Jun 16, 2013
    #12
  13. glen herrmannsfeldt <> writes:
    > Keith Thompson <> wrote:
    > (snip)
    >> It does make sense to use a typedef when the type is opaque, i.e., when
    >> code that uses the type is not expected to be written to depend on the
    >> fact that the type is a struct. Type FILE is a good example of this;
    >> it's likely to be a typedef for a struct, but portable code that uses
    >> type FILE cannot refer to its members or assume that it's a struct.

    >
    > Yes, I don't normally used typedef on my structs, but I do like
    > FILE not being stuct FILE. Then again, how much does typedef
    > help over #define?


    I suspect that FILE was originally a macro. Typedefs were a
    relatively late addition to the language, and it's likely that FILE
    predates them. That could explain why its name is in all caps.

    Typedefs have better scoping (though I think most types are defined at
    file scope, so that's not a huge advantage). They can also result in
    better error messages; the compiler tell you that function expects a
    FILE* argument rather than a struct _IO_FILE (or whatever) argument.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 16, 2013
    #13
  14. Tim Rentsch <> writes:
    > Keith Thompson <> writes:
    >> Tim Rentsch <> writes:
    >>> Keith Thompson <> writes:
    >>>> "paskali" <> writes:
    >>>>> 1st:
    >>>>>
    >>>>> struct person {
    >>>>> char *name;
    >>>>> char *surname;
    >>>>> };
    >>>>
    >>>> That's my own preference. The type has a name "struct person";
    >>>> I don't feel the need to give it another one.
    >>>
    >>> How this is expressed seems a little funny to me. Does this mean
    >>> you think there is never any reason to give a structure type a
    >>> different name (ie, using typedef)? Or only that there is never
    >>> a _need_ to do so? Or that there usually is not a need to do so?
    >>> Or what?

    >>
    >> I'm not sure it *means* that, but there is never a *need* to give a
    >> struct type another name. If the language didn't permit typedefs for
    >> structs, it would not lose any real expressive power.
    >>
    >> For example, <time.h> defines a type "struct tm". It doesn't define a
    >> typedef for it. IMHO such a typedef is not necessary, and would not be
    >> particularly beneficial.
    >>
    >> An advantage of a typedef is that it gives the type a name that's a
    >> single identifer. I don't see that as a particularly important
    >> advantage. Others do.
    >>
    >> It does make sense to use a typedef when the type is opaque, i.e., when
    >> code that uses the type is not expected to be written to depend on the
    >> fact that the type is a struct. Type FILE is a good example of this;
    >> it's likely to be a typedef for a struct, but portable code that uses
    >> type FILE cannot refer to its members or assume that it's a struct.

    >
    > Let me ask my question(s) more directly. What are the benefits of
    > using a typedef name for struct types (as opposed to using 'struct'
    > and a tag)? What are the costs? In which cases do the costs (a)
    > clearly outweigh the benefits, (b) clearly underweigh the benefits,
    > and (c) approximately balance the benefits? The third question is
    > meant to elicit opinion, the first two more objective assessments.


    The costs and benefits are minor. I've acknowleged before that plenty
    of smart people prefer to use typedefs for structs. I have no great
    problem with that; I just prefer not to in my own code.

    Omitting the typedef means there's (at least) one less thing to get
    wrong. If, hypothetically, the language didn't permit typedefs for
    structs, then this conversation would be unnecessary.

    And I suggest that if you're going to *add* a declaration to a piece of
    code, the burden of proof should be on the argument in favor of adding
    it. If it doesn't help, why do it?

    Also, I've seen too much code that defines both a struct tag and
    a typedef name for the same type, with no obvious relationship
    between the two names. That's confusing. Dropping the typedef
    removes that particular source of confusion.

    What's *your* opinion on the matter?

    [...]

    >> I'm not *deliberately* ducking the question, I just didn't feel like
    >> writing about it at great length. If you're going to define a typedef
    >> for a struct, IMHO it's better to use the same identifier for the tag
    >> and the typedef name. I can think of no good reason to make the
    >> identifiers distinct.

    >
    > The names are in different namespaces; different style rules,
    > coding standards, or other considerations, may apply in the
    > two cases.


    Of course I'll follow coding standards for existing code that I'm
    working on. I can't think of a good reason for a coding standard
    or style rule to require a struct tag and a typedef to have distinct
    names (other than perhaps the one you mention below).

    > It may be useful to have the two names be different to reduce the
    > possibility of confusion.


    If you know that "foo" and "struct foo" are the same type, what
    confusion is avoided by calling them "foo" and "struct foo_s", for
    example -- or "foo" and "struct bar"?

    > It may be useful to have the two names be different to deliberately
    > make it harder to use the other name, eg,
    >
    > typedef struct foo_avoid_using_this_struct_tag foo;


    Ok, that's a valid reason. I note that this still implies a consistent
    convention.

    >> If you're going to use distinct identifiers, I think you should
    >> at least follow a consistent convention, such as appending "_t"
    >> to the tag name to form the typedef name (though I think POSIX
    >> reserves identifiers ending in "_t" for some purposes).

    >
    > Certainly there is some benefit to doing this, but there also
    > can be benefit from not necessarily tying the two names together in
    > all cases. In either case I don't think it matters very much;
    > typically I expect the struct tag would appear on only two or
    > three places for those structs having both a tag and a typedef
    > name.


    You say "in all cases". Are there some cases where they should have the
    same name, and other cases where they shouldn't? How are such cases
    distinguished?

    [...]

    >> Referring to a type as "struct foo" makes it clear to the reader
    >> that it's a struct type. Referring to it as "foo" does not.
    >> All else being equal, more clarity is better than less clarity.
    >> Where's the tautology?

    >
    > Oh, but now you're saying something different. Your earlier
    > statement didn't say anything about clarity, only about being
    > explicit. They are not synonymous.


    They're not synonymous, but they're related.

    > Furthermore the idea that adding information necessarily adds
    > clarity is, at the very least, subject to debate. If that were
    > true, then why not do this:
    >
    > struct foo_int_x_double_z {
    > int x;
    > double z;
    > };
    >
    > Now we know just from a declaration what members and member types a
    > struct has! Obviously this suggestion is meant rhetorically, but I
    > hope you can see my point. Including the keyword 'struct' in each
    > and every declaration that uses the underlying structure type may
    > not necessarily lead to code that is easier to understand, and
    > certainly not always significantly easier to understand.


    Sure, I see your point. I have my own preferences about how explicit
    code should be. They differ from the preferences of a lot of other
    C programmers -- and they're not always internally consistent.

    My bottom line about typedefs for structs is that a typedef doesn't
    add anything very useful. (I don't consider the ability to use a
    single identifier for a type name to be very useful; YMMV).

    Part of it, I suppose, is my tendency to think of C code in terms
    of the underlying semantics. Given "typedef struct foo { ... }
    foo;", I think of "struct foo" as the *real* name of the type, and
    "foo" as a mere alias. Others might have a mental model that says
    "foo" is the real name of the type.

    > Also, and perhaps most important, is the point you gloss over:
    > "all else being equal". It is precisely because all else is not
    > equal that the question is raised. If you don't consider both
    > benefits AND costs, and make an effort to weigh one against the
    > other, any conclusions reached are unlikely to have much value.
    > Do you agree with that? If you don't I'm very curious to hear
    > why not.


    I don't exhaustively explore all the possible benefits and costs every
    time I write about typedefs. A lot of what I post here is probably too
    long as it is.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 16, 2013
    #14
  15. Tim Rentsch

    Ian Collins Guest

    Tim Rentsch wrote:
    > Keith Thompson <> writes:
    >
    >> Tim Rentsch <> writes:
    >>> Keith Thompson <> writes:
    >>>> "paskali" <> writes:
    >>>>> 1st:
    >>>>>
    >>>>> struct person {
    >>>>> char *name;
    >>>>> char *surname;
    >>>>> };
    >>>>
    >>>> That's my own preference. The type has a name "struct person";
    >>>> I don't feel the need to give it another one.
    >>>
    >>> How this is expressed seems a little funny to me. Does this mean
    >>> you think there is never any reason to give a structure type a
    >>> different name (ie, using typedef)? Or only that there is never
    >>> a _need_ to do so? Or that there usually is not a need to do so?
    >>> Or what?

    >>
    >> I'm not sure it *means* that, but there is never a *need* to give a
    >> struct type another name. If the language didn't permit typedefs for
    >> structs, it would not lose any real expressive power.
    >>
    >> For example, <time.h> defines a type "struct tm". It doesn't define a
    >> typedef for it. IMHO such a typedef is not necessary, and would not be
    >> particularly beneficial.
    >>
    >> An advantage of a typedef is that it gives the type a name that's a
    >> single identifer. I don't see that as a particularly important
    >> advantage. Others do.
    >>
    >> It does make sense to use a typedef when the type is opaque, i.e., when
    >> code that uses the type is not expected to be written to depend on the
    >> fact that the type is a struct. Type FILE is a good example of this;
    >> it's likely to be a typedef for a struct, but portable code that uses
    >> type FILE cannot refer to its members or assume that it's a struct.

    >
    > Let me ask my question(s) more directly. What are the benefits of
    > using a typedef name for struct types (as opposed to using 'struct'
    > and a tag)? What are the costs? In which cases do the costs (a)
    > clearly outweigh the benefits, (b) clearly underweigh the benefits,
    > and (c) approximately balance the benefits? The third question is
    > meant to elicit opinion, the first two more objective assessments.


    The first two are also subjective because one programmer's benefit is
    another programmer's cost. Keith would probably say having to write
    "struct Foo foo" rather than "Foo foo" improves clarity where I would
    claim it adds clutter. Yes the first form makes it clear Foo is a
    struct, but does it really matter? Maybe I'm looking at the question
    from a C++ as well as a C programmer's perspective, but I doubt you
    could find a case were nature of Foo both matters and isn't clear from
    the context of the declaration.

    --
    Ian Collins
     
    Ian Collins, Jun 16, 2013
    #15
  16. Tim Rentsch

    Tim Rentsch Guest

    Ike Naar <> writes:

    > On 2013-06-16, Tim Rentsch <> wrote:
    >> Ike Naar <> writes:
    >>
    >>> On 2013-06-16, glen herrmannsfeldt <> wrote:
    >>>> Yes, I don't normally used typedef on my structs, but I do like
    >>>> FILE not being stuct FILE. Then again, how much does typedef
    >>>> help over #define?
    >>>
    >>> typedef works in non-trivial cases where #define doesn't.
    >>>
    >>> struct thing { int i; double d; };
    >>>
    >>> typedef struct thing thing, thing2[2];
    >>>
    >>> thing a_thing;
    >>> thing2 a_thing2;
    >>>
    >>> How would you do this, using #define instead of typedef?

    >>
    >> Surely the question is meant to ask about using #define
    >> only for the name of the struct type, not for more
    >> complicated type constructors like arrays.

    >
    > Okay, but even in the simple case #define is not better
    > then typedef. So I would like the re-phrase Glen's question:
    > how much does #define help over typedef?


    In terms of just linguistic rules I don't think there's a big
    difference between them. Names defined as macros ignore scoping
    rules, whereas typedef names do not. Also just doing a #define
    doesn't declare the structure type, so a separate declaration
    would usually be necessary in that case.

    I can imagine cases where using #define would interact better
    with other aspects of whatever source tools are used. For
    example, a debugger might understand a type name written using
    'struct' and a structure tag better than a name defined using
    typedef; if one were using such a debugger, that might be
    an argument in favor of using #define. (Disclaimer: I can
    imagine such cases but I can't think of any actual ones right
    off the top of my head.)

    I think the main forces favoring using typedef have to do with
    developer culture more than they do with technical implications.
    The first of these is consistency: because typedef is better for
    defining other kinds of types, using #define just for structs
    would be less consistent. The other big one is a sort of an
    unwritten law that most C developers follow, namely, use the
    preprocessor only when forced (practically speaking) to do so.
    These forces make the energy barrier for using #define rather
    than typedef pretty high.
     
    Tim Rentsch, Jun 19, 2013
    #16
  17. Tim Rentsch

    2dealsok

    Joined:
    Jun 19, 2013
    Messages:
    4
    Location:
    http://www.lcdinverter.info/
    Read:):无聊::无聊:
     
    2dealsok, Jun 19, 2013
    #17
  18. Tim Rentsch

    Tim Rentsch Guest

    Ian Collins <> writes:

    > Tim Rentsch wrote:
    >> Keith Thompson <> writes:
    >>
    >>> Tim Rentsch <> writes:
    >>>> Keith Thompson <> writes:
    >>>>> "paskali" <> writes:
    >>>>>> 1st:
    >>>>>>
    >>>>>> struct person {
    >>>>>> char *name;
    >>>>>> char *surname;
    >>>>>> };
    >>>>>
    >>>>> That's my own preference. The type has a name "struct person";
    >>>>> I don't feel the need to give it another one.
    >>>>
    >>>> How this is expressed seems a little funny to me. Does this mean
    >>>> you think there is never any reason to give a structure type a
    >>>> different name (ie, using typedef)? Or only that there is never
    >>>> a _need_ to do so? Or that there usually is not a need to do so?
    >>>> Or what?
    >>>
    >>> I'm not sure it *means* that, but there is never a *need* to give a
    >>> struct type another name. If the language didn't permit typedefs for
    >>> structs, it would not lose any real expressive power.
    >>>
    >>> For example, <time.h> defines a type "struct tm". It doesn't define a
    >>> typedef for it. IMHO such a typedef is not necessary, and would not be
    >>> particularly beneficial.
    >>>
    >>> An advantage of a typedef is that it gives the type a name that's a
    >>> single identifer. I don't see that as a particularly important
    >>> advantage. Others do.
    >>>
    >>> It does make sense to use a typedef when the type is opaque, i.e., when
    >>> code that uses the type is not expected to be written to depend on the
    >>> fact that the type is a struct. Type FILE is a good example of this;
    >>> it's likely to be a typedef for a struct, but portable code that uses
    >>> type FILE cannot refer to its members or assume that it's a struct.

    >>
    >> Let me ask my question(s) more directly. What are the benefits of
    >> using a typedef name for struct types (as opposed to using 'struct'
    >> and a tag)? What are the costs? In which cases do the costs (a)
    >> clearly outweigh the benefits, (b) clearly underweigh the benefits,
    >> and (c) approximately balance the benefits? The third question is
    >> meant to elicit opinion, the first two more objective assessments.

    >
    > The first two are also subjective because one programmer's benefit is
    > another programmer's cost. [snip elaboration]


    Yes and no. As long as the statements of "costs" and "benefits"
    are objective assessments it doesn't matter to the final outcome
    which labels are used in individual cases. Looking at someone's
    proposed list, I might be surprised to see attribute X listed as
    a "cost" when I think of it as a "benefit", or vice versa, but
    it's easy for me to account for that just by giving attribute X a
    negative weight in my (subjective) weighting function. The key
    point is to divide the analysis into an objective portion and a
    subjective portion. In many cases there will be pretty strong
    consensus on whether a particular attribute is seen as a "cost"
    or a "benefit", but whether there is or not doesn't limit the
    downstream (subjective) discussion or what overall conclusions
    can be reached. If the "cost"/"benefit" labels represent shared
    opinion, that's fine; when they don't, it's easy to reflect that
    simply by using negative weights in your weighting function.
     
    Tim Rentsch, Jun 19, 2013
    #18
  19. Tim Rentsch

    Tim Rentsch Guest

    Tiib <> writes:

    > On Sunday, 16 June 2013 18:15:56 UTC+3, Tim Rentsch wrote:
    >>[snip]
    >>
    >> It is also true that
    >>
    >> typedef struct person_structure_tag {
    >> char *name;
    >> char *surname;
    >> } person;
    >>
    >> allows the use of 'person' as a type name in both C and C++.

    >
    > For me that is also fine. I dislike habit of some compilers
    > to discuss "struct person_structure_tag" as result in some
    > diagnostics, but that is minor.
    >
    > However 'struct person', (that several people said to be their
    > favorite form of usage) is not available with this definition
    > (it is with "3th" in both languages). I like when interfaces are
    > least intrusive when it comes to favorite styles of usage.


    I emphatically disagree with this reaction. Every style guide
    I have ever read recommends consistency. Encouraging or
    accommodating the use of multiple ways of doing the same thing
    is just wrong. Furthermore part of the point of using the
    longer name as a structure tag is so that 'struct person'
    _cannot_ be used; that C++ allows it is simply an unfortunate
    consequence of C++'s design choices.

    >> Moreover, this form relies less on knowing what the C++ rules
    >> are for how names of struct types are handled, which clearly
    >> is an advantage for people coming from a C background.

    >
    > If it is interface that is meant for usage in both languages
    > (possibly by third parties with unknown taste in style) then the
    > better the authors know both languages the easier to everybody.
    > If it is not such interface then it does not matter.


    Even if I agreed with this implication, the premise doesn't
    match how things actually are currently, nor is it likely to
    anytime in the near future. Design decisions should be made
    based on how the world actually is, not on wishful thinking.
     
    Tim Rentsch, Jun 19, 2013
    #19
  20. Tim Rentsch

    Öö Tiib Guest

    On Wednesday, 19 June 2013 20:05:19 UTC+3, Tim Rentsch wrote:
    > Tiib <> writes:
    > > On Sunday, 16 June 2013 18:15:56 UTC+3, Tim Rentsch wrote:
    > >>[snip]
    > >>
    > >> It is also true that
    > >>
    > >> typedef struct person_structure_tag {
    > >> char *name;
    > >> char *surname;
    > >> } person;
    > >>
    > >> allows the use of 'person' as a type name in both C and C++.

    > >
    > > For me that is also fine. I dislike habit of some compilers
    > > to discuss "struct person_structure_tag" as result in some
    > > diagnostics, but that is minor.
    > >
    > > However 'struct person', (that several people said to be their
    > > favorite form of usage) is not available with this definition
    > > (it is with "3th" in both languages). I like when interfaces are
    > > least intrusive when it comes to favorite styles of usage.

    >
    > I emphatically disagree with this reaction. Every style guide
    > I have ever read recommends consistency. Encouraging or
    > accommodating the use of multiple ways of doing the same thing
    > is just wrong.


    It is impossible to be consistent when each library that is used
    pushes their yet another viewpoint of what is "not wrong style".

    > Furthermore part of the point of using the
    > longer name as a structure tag is so that 'struct person'
    > _cannot_ be used; that C++ allows it is simply an unfortunate
    > consequence of C++'s design choices.


    If language design choices of C++ are so unfortunate and bad then
    how come that so lot (statistically most) of finalists of all language
    neutral programming contests are using it? C++ is useful tool.
    It is pointless to fight with a tool anyway.

    I believe that "person" is enough and "struct" is redundant, but
    if someone else feels that explicit "struct person" is more clear
    then the 5 letters can not hurt me. I write them myself when coding
    standard of particular product I work on suggests so.

    > >> Moreover, this form relies less on knowing what the C++ rules
    > >> are for how names of struct types are handled, which clearly
    > >> is an advantage for people coming from a C background.

    > >
    > > If it is interface that is meant for usage in both languages
    > > (possibly by third parties with unknown taste in style) then the
    > > better the authors know both languages the easier to everybody.
    > > If it is not such interface then it does not matter.

    >
    > Even if I agreed with this implication, the premise doesn't
    > match how things actually are currently, nor is it likely to
    > anytime in the near future. Design decisions should be made
    > based on how the world actually is, not on wishful thinking.


    How they are currently? I had impression that we currently are
    not discussing design but style. Style ... how struct names are
    arranged and used.
     
    Öö Tiib, Jun 19, 2013
    #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. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    934
    Mark Rae
    Dec 21, 2006
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,128
    Smokey Grindel
    Dec 2, 2006
  3. Peter Bencsik
    Replies:
    2
    Views:
    866
  4. Andrew Thompson
    Replies:
    8
    Views:
    161
    Premshree Pillai
    Jun 7, 2005
  5. Replies:
    2
    Views:
    63
    Mark H Harris
    May 13, 2014
Loading...

Share This Page