简体   繁体   中英

Getting -Wincompatible-pointer-types for struct pointer warning when compiling

I'm following along with this tutorial to learn about external chaining in Hashtables in C. I find that I get the following error when compiling with gcc --std=c99 :

warning: assignment to "person *" {aka 'struct <anonymous> *'} from incompatible pointer type 'struct person *' [-Wincompatible-pointer-types]
101 | tmp = tmp->next;

warning: assignment to "person *" {aka 'struct <anonymous> *'} from incompatible pointer type 'struct person *' [-Wincompatible-pointer-types]
112 | p->next = hash_table[index];

warning: assignment to "person *" {aka 'struct <anonymous> *'} from incompatible pointer type 'struct person *' [-Wincompatible-pointer-types]
121 | tmp = tmp->next;

warning: assignment to "person *" {aka 'struct <anonymous> *'} from incompatible pointer type 'struct person *' [-Wincompatible-pointer-types]
132 | tmp = tmp->next;

warning: assignment to "person *" {aka 'struct <anonymous> *'} from incompatible pointer type 'struct person *' [-Wincompatible-pointer-types]
136 | hash_table[index] = tmp->nxt;

I find that this occurs only with the next pointer for the person struct:

typedef struct {
   char name[TABLE_SIZE];
   int age;
   //...
   struct person *next;
} person;

For functions like these:

void print_table(){
   for (int i=0; i < TABLE_SIZE; i++0 {
       if (hash_table[i] == NULL) {
           printf("\t%i\t---n\n",i);
       }
       else {
            printf("\t%i\t",i);
            person *tmp = hash_table[i];
            while (tmp != NULL) {
                printf("%s -", tmp->name);
                tmp = tmp->next;
            }
            printf("\n");
       }
   }
}

bool hash_table_insert(person *p) {             
    if (p == NULL) return false;                
    int index = hash(p->name);
    p->next = hash_table[index];
    hash_table[index] = p;
    return true; 
}

The hashtable's output is correct so clearly it works fine but it gets these warnings. I did not get these warnings until implementing the chaining technique. I'm inclined to believe it has something to do with the addition of struct person *next; , or at least it's usage. Any ideas?

This typedef declaration

typedef struct {
   char name[TABLE_SIZE];
   int age;
   //...
   struct person *next;
} person;

declares an unnamed structure with the typedef name person , and this record within the unnamed structure

   struct person *next;

introduces an incomplete type specifier struct person .

Thus person and struct person are two different type specifiers.

You could, for example

typedef struct person person;

struct person {
   char name[TABLE_SIZE];
   int age;
   //...
   struct person *next;
};

or

typedef struct person {
   char name[TABLE_SIZE];
   int age;
   //...
   struct person *next;
} person;

An anonymous struct is a struct without a tag . Give your struct a tag and then use struct person everywhere.

And don't bother with typedefs for structs. All they do is save you from typing struct in a few places, like declarations.

struct person {
   char name[TABLE_SIZE];
   int age;
   //...
   struct person *next;
};
...
struct person *tmp = hash_table[i];

On another note, functions taking no arguments should be declared with a (void) argument list, otherwise they indicate an unspecified but fixed argument list. In particular, in C, something like

int foo();

is not a prototype! It's an old-style (K&R C) function declaration from the age when C did not have the void keyword.

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