“warning: useless storage class specifier in empty

2019-03-20 11:18发布

问题:

typedef struct item {
    char *text;
    int count;
    struct item *next;
};

So I have this struct with nodes defined as above, but Im getting the error below and Im not able to figure out whats wrong.

warning: useless storage class specifier in empty declaration };

回答1:

I'm not sure, but try like that :

typedef struct item {
  char *text;
  int count;
  struct item *next;
}item;


回答2:

The typedef is useless because you didn't give it a name. You cannot use the typedef in any way. That's why you get a warning, because the typedef is useless.



回答3:

The struct is actually still usable without the warning if you remove the typedef keyword like this:

struct item {
    char *text;
    int count;
    struct item *next;
};

You just need to include the 'struct' keyword in the variable declaration. i.e.

struct item head;

as other have pointed out if you include the name at the end of the struct definition then you can use it as the typedef and you get rid of the warning even without the struct keyword but this makes the first instance of 'item' superfluous i.e.

typedef struct {
    char *text;
    int count;
    struct item *next;
} item;

item head;

will also get rid of the warning.



回答4:

typedef is used to create a shorthand notation for an existing type in C. It is similar to #define but unlike it, typedef is interpreted by the compiler and offers more advanced capabilities than the preprocessor.

With its simplest form, typedef is given as

typedef existing_type new_type;

for instance,

typedef unsigned long UnsignedLong;

For example, if you trace the definition of size_t back to its root, you will see that

/* sys/x86/include/_types.h in FreeBSD */
/* this is machine dependent */
#ifdef  __LP64__
typedef unsigned long       __uint64_t;
#else
__extension__
typedef unsigned long long  __uint64_t;
#endif
...
...
typedef __uint64_t  __size_t;   

and then

/* stddef.h */
typedef __size_t    size_t;

which actually means, size_t is an alias for unsigned long long,depending on the 64-bit modal (LP64, ILP64, LLP64) your machines has.

For your question, you attempt to define a new type but do not name it. Don't let the struct item {..} definition confuse you, it is just a type you are declaring. If you replace the whole struct item {...} with a basic type, say with an int, and rewrite your typedef, you would end up something like this

typedef int; /* new type name is missing */

the correct form should be

typedef struct item {...} Item;

See the examples below for different structure definitions

#include <stdio.h>

/* a new type, namely Item, is defined here */
typedef struct item_t {
  char *text;
  int count;
  struct item_t *next; /* you canot use Item here! */
} Item;

/* a structure definition below */
struct item {
  char *text;
  int count;
  struct item *next;
};

/* an anonymous struct
* However, you cannot self-refence here 
*/
struct {
  int i;
  char c;
} anon;

int main(void) {
  /* a pointer to an instance of struct item */
  struct item *pi;

  /* Shorthand for struct item_t *iI */
  Item *iI;

  /* anonymoous structure */
  anon.i = 9;
  anon.c = 'x';
  return 0;
}