简体   繁体   中英

Useless variable name in C struct type definition

I'm implementing a linked list in C. Here's a struct that I made, which represents the linked list:

typedef struct llist {
  struct lnode* head; /* Head pointer either points to a node with data or NULL */
  struct lnode* tail; /* Tail pointer either points to a node with data or NULL */
  unsigned int size; /* Size of the linked list */
} list;

Isn't the "llist" basically useless. When a client uses this library and makes a new linked list, he would have the following declaration:

list myList;

So typing llist just before the opening brace is practically useless, right? The following code basically does the same job:

typedef struct {
  struct lnode* head; /* Head pointer either points to a node with data or NULL */
  struct lnode* tail; /* Tail pointer either points to a node with data or NULL */
  unsigned int size; /* Size of the linked list */
} list;

You need to give a struct a name if you will reference it in its declaration.

typedef struct snode {
    struct snode* next;
    struct snode* prev;
    int id;
} node;

But if you won't reference the struct inside it you dont need to give it a name.


EDIT

Notice that typedef is and struct are two different statements in C.

struct is for creating complex types:

struct snode {
    struct snode* next;
    struct snode* prev;
    int id;
};

Which reads like make a structure called snode that stores two references to itself ( next and prev ) and an int ( id ) .

And typedef is for making type aliases :

typedef struct snode node;

Which reads like make a type alias for struct snode called node .

Yes, you are correct. It is only a matter of habit or convention to explicitly name the struct in addition to the typedef.

Note that there is little to no cost either way, since llist is not a variable and does not take up memory. It is like the difference between naming a variable i or index - the compiled form is the same, but one may be more readable than the other.

It's useless in that particular case but, if you wanted a pointer to that struct within the struct itself, it would be needed.

That's because the struct is known at the opening brace while the typedef isn't known until the final semicolon (simplistic, but good enough here).

So you would need it for something like:

typedef struct sNode {  // structure can be used now
    int payload;
    struct sNode *next; // cannot use typedef yet
} tNode;                // typedef can be used now

You could turn this around: not the structure tag, but the whole typedef is superfluous.

struct snode {
    struct snode* next;
    struct snode* prev;
    int id;
    };

Now you can declare a pointer with:

struct snode *ptr;

You can even declare an array of them:

struct snode mynodes[10];

You'll have to type the struct keyword, but that won't hurt the compiler or the human reader (look at that syntax highlighting!).

You could even declare a pointer to an unknown type (at this moment of compilation) using an incomplete type :

struct xnode *xptr=NULL;

That will come in handy when you want to create an API to some library, where the actually implementtation of the library is not known to the caller:

 struct gizmo *open_gizmo(char *path, int flags);
 int fiddle_with_gizmo(struct gizmo *ptr, int opcode, ...);

Et cetera. A typedef would force the header file to "broadcast" all its internals to the caller, even if that is not needed.

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