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?
CodePudding user response:
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;
CodePudding user response:
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.