Reputation: 1264
I am trying to implement linked list like in Linux Kernel.
I think my header file is fine but when I try to compile my main file to test what I did I do not really understand what is wrong ...
my file list.h :
#ifndef _LIST_H
#define _LIST_H
struct list_head {
struct list_head *next, *prev;
};
static inline void
INIT_LIST_HEAD (struct list_head *head)
{
head->next = head->prev = head;
}
static inline void
list_add (struct list_head *node,struct list_head *head)
{
head->next->prev = node;
node->next = head->next;
node->prev = head;
head->next = node;
}
static inline void
list_del (struct list_head *node)
{
node->next->prev = node->prev;
node->prev->next = node->next;
}
#define container_of(ptr, type, member) ({\
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type, member) );})
#define list_for_each_entry(cur, head, member) \
for (cur = container_of((head)->next, typeof(*cur),member);&cur->member != (head); \
cur = container_of(cur->member.next,typeof(*cur), member))
#endif /* _LIST_H */
my main file :
#include <stdlib.h>
#include <stdio.h>
#include "list.h"
struct kool_list{
int to;
struct list_head list;
int from;
};
int
main(){
struct kool_list *tmp;
struct list_head *pos, *q;
unsigned int i;
struct kool_list mylist;
INIT_LIST_HEAD(&mylist.list);
/* adding elements to mylist */
for(i=5; i!=0; --i){
tmp= (struct kool_list *)malloc(sizeof(struct kool_list));
printf("enter to and from:");
scanf("%d %d", &tmp->to, &tmp->from);
list_add(&(tmp->list), &(mylist.list));
}
printf("\n");
printf("traversing the list using list_for_each_entry()\n");
list_for_each_entry(tmp, &mylist.list, list)
printf("to= %d from= %d\n", tmp->to, tmp->from);
printf("\n");
return 0;
}
And when I compile it with gcc *.c -o main I get the following errors :
In file included from main.c:3:0:
main.c: In function ‘main’:
list.h:35:41: error: expected expression before ‘typeof’
for (cur = container_of((head)->next, typeof(*cur),member);&cur->member != (head); \
^
list.h:32:37: note: in definition of macro ‘container_of’
(type *)( (char *)__mptr - offsetof(type, member) );})
^
main.c:77:2: note: in expansion of macro ‘list_for_each_entry’
list_for_each_entry(tmp, &mylist.list, list)
^
list.h:36:39: error: expected expression before ‘typeof’
cur = container_of(cur->member.next,typeof(*cur), member))
^
list.h:32:37: note: in definition of macro ‘container_of’
(type *)( (char *)__mptr - offsetof(type, member) );})
^
main.c:77:2: note: in expansion of macro ‘list_for_each_entry’
list_for_each_entry(tmp, &mylist.list, list)
^
It seems that I don't manipulate 'typeof' the right way but I don't get why... If anybody could explain what is wrong, thank you :)
Upvotes: 2
Views: 1600
Reputation: 13370
Your error is caused by missing an include - offsetof
isn't a builtin operator (like sizeof
), but rather a true macro, defined in stddef.h
.
Without this file included the compiler assumes it must refer to a function, which causes the compiler to completely misinterpret the syntax and give you an unclear error message (since functions can't accept types as their arguments).
You can fix the immediate syntax error by including stddef.h
. You can get more insight into what's going wrong in these situations by compiling with as many strict switches and warnings enabled as possible (at the very least, use -Wall
). GCC compiles in quite a permissive mode by default, which among other things, doesn't consider implicit function declaration to be an error, so the real root cause of this problem was being completely ignored by the compiler.
Upvotes: 3