Why use different a different tag and typedef for a struct?

后端 未结 5 509
离开以前
离开以前 2020-12-09 20:11

In C code, I\'ve seen the following:

typedef struct SomeStructTag {
    // struct members
} SomeStruct;

I\'m not clear on why this is any d

相关标签:
5条回答
  • 2020-12-09 20:42

    In most cases, one could use the same name for both purposes without any problem. The practice of people using different names in code probably stems from the days before ANSI standardization, when there were a lot of compilers that accepted mostly-compatible dialects of something resembling C. Some constructs and features would work on almost any compiler, others would work on most (but fail on a significant number), and others would only work on a few. Although the standard has for many years clearly mandated that there are different namespaces for types, structure tags, and for the members of each individual structure, some compilers from the early days didn't recognize all those namespaces as distinct, a fair amount of code was written which was supposed to work even with such compilers, and people tend to write code which resembles other code they've seen.

    I think the strongest objection to using the same identifier given today's rules would be the principle that distinct identifiers should look distinct, and one should generally avoid using two semantically-equivalent identifiers for a given purpose. It's fine to use two distinct identifiers for some purpose if there's some clear semantic distinction between them (e.g. "the fastest type that's at least 32 bits" versus an "exactly 32 bits" type), but it's not good to have code use two different identifiers for the same purpose essentially at random. If one declares typedef struct FOO {...} FOO;, then struct FOO and FOO will be distinct identifiers that look as though they should be interchangeable. If there are particular cases where one is supposed to use one or the other and the names are distinct, then typing struct where one shouldn't, or vice versa, will cause a compilation error. If the names match, things would compile and there would be no warning that the usage of the name wasn't consistent with its usage elsewhere.

    Incidentally, although struct tags are globally available, there often isn't any need to use any tag more than once. Even if a struct is supposed to contain self-referential pointers, one may, in ANSI C, declare it:

    typedef struct NODE_S NODE;
    struct NODE_S {
      NODE *parent,*left,*right;
    };
    

    without having to refer to the type as struct NODE_S anywhere except the particular line declaring the typedef name. Everywhere else, one may instead simply use the typedef name directly.

    0 讨论(0)
  • 2020-12-09 20:48

    There is no reason within the C standard to use different names for tags and types. They cannot interfere with each other because they are in different name spaces and cannot be used in the same places.

    Therefore, the only reason to use different names would be for human psychology. Although other answers have suggested that using different names for tags and types makes it easier to spot them in code, there is never any ambiguity because structure tag names only appear after struct, and only structure tag names appear after struct. More than that, if they are the same, you cannot accidentally use one where you intend the other. So there is no need to use different names.

    The fact that C++ adopted structure tags as class names demonstrates it is unnecessary for there to be any difference.

    0 讨论(0)
  • 2020-12-09 20:51

    The point is that SomeStruct will then be a proper type name. So you don't have to type

    struct SomeStructTag my_struct;
    

    In declarations:

    SomeStruct my_struct;
    

    Other than that, IMHO the _t appended to a name stands for type, not tag.

    0 讨论(0)
  • 2020-12-09 20:56

    The reason is that struct tags and typedef names are in different namespaces in C. You can only use a struct tag after the keyword struct, so it is handy to know which is which.

    In C++ they are in the same namespace so the issue doesn't arise. Which also means your second example may not be legal C++. Your first example is legal in both languages.

    0 讨论(0)
  • 2020-12-09 20:58

    There is one functional reason for using a different tag between the typedef and the struct. This is when you're doing a linked list structure, where one of the fields in your struct is a pointer to an instance of the struct being defined. Since the statement isn't complete yet, you can't use the typedef name within the statement.

    For example:

    typedef struct {
        link_t* next;
        void*   data;
    } link_t;
    

    won't work, because you're trying to use link_t before the compiler has seen the symbol. Instead, you write it so:

    typedef struct LL {
        struct LL* next;
        void*      data;
    } link_t;
    

    and struct LL is known to the compiler one line before you use it.

    0 讨论(0)
提交回复
热议问题