简体   繁体   中英

Typedef struct wrong declaration?

I referred to the tutorial below and later realized it is wrong way of declaring struct using typedef.

 typedef struct

 {
  char name[namesize];
  char address[addresssize];
  int YearOfBirth;
  int MonthOfBirth;
  int DayOfBirth;
} PersonalData;

then declare:

PersonalData x;

However, I believe the right way is

 typedef struct personaldataStruct
 {
  char name[namesize];
  char address[addresssize];
  int YearOfBirth;
  int MonthOfBirth;
  int DayOfBirth;
  } PersonalData;

then declare:

  PersonalData x;

Did the author mislead me? or both ways are correct? please confirm. Here is the tutorial http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

There's nothing formally "incorrect" about either approach.

The former declares a tag-less struct type and a typedef name PersonalData for that struct type. The latter declares a struct type struct personaldataStruct and a synonymous typedef name PersonalData for that struct type. The personaldataStruct part of the declaration is commonly referred as a "struct tag".

As long as you use PersonalData typedef name for referring to that struct type, as in

PersonalData x;

you will not see any difference between the two declarations. In both cases x will be declared identically.

The latter approach provides you with an alternative way of referring to the same struct type - struct personaldataStruct - if for some reason you will wish to do so. Eg when using the latter declaration, you can also declare your x as

struct personaldataStruct x;

which is exactly equivalent to the PersonalData x; declaration.

Personally, I prefer to use the approach with struct tag, since it provides me with alternative way of referring to the type, which might come handy in some situations (for example, when the struct type has to refer to itself). But in most non-self-referential cases one will be perfectly fine with the former approach.

Both are correct. The only real problem with the first form (without the tag) is that, because the typedef name doesn't become visible until the end of the definition, there's no way to refer to the structure from within its own definition. That's a common requirement; for example, a node in a linked list, tree, or other graph-like data structure commonly needs to point to other objects of the same type.

Since struct tags and typedef names are in different namespaces (not to be confused with C++ namespaces), there's no need for them to be distinct. It's perfectly acceptable to use the same identifier for both:

typedef struct PersonalData {
    /* ... */
    struct PersonalData *next;
} PersonalData;

Or, as long as you're going to have both a tag and a typedef anyway, you can forward declare the typedef:

typedef struct PersonalData PersonalData;
/* At this point, "struct PersonalData is an incomplete type. */
struct PersonalData {
    /* ... */
    PersonalData *next;
};
/* And now "struct PersonalData" is a complete type. */

(But a misspelling can leave you with a typedef that still refers to an incomplete type that's never completed, which can trigger errors that can be difficult to track down. Copy-and-paste is your friend.)

And there is another alternative. The type you've defined already has a name: struct PersonalData . All the typedef does is give that same type a different name. It's nice to be able to use a single identifier as a type name, but it's really not necessary. My own preference is to omit the typedef altogether, and just refer to the type as struct PersonalData :

struct PersonalData {
    /* ... */
    struct PersonalData *next;
};
struct PersonalData *head;
struct PersonalData fred;

Unless PersonalData is meant to be an opaque type (meaning that code that uses it doesn't need to know that it's a struct), there's some advantage in being explicit.

Plenty of people strongly disagree with me on this point, and really like using typedefs for structures, as you'll probably see in comments. There's nothing wrong with using typedefs like this; it's just not necessary. You should be prepared to read code written by others using either style.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM